@RabbitHu
2017-09-17T16:51:57.000000Z
字数 1758
阅读 1258
作业
给定,求合法的组数,对取模。
一组是合法的,当且仅当:
1.
2.
数据范围:
首先所有的都是n的因数,总的种数不会超过.
所有的组可以分为三类:乘积等于,乘积小于,乘积大于.
乘积小于的组和乘积大于的组是一一对应的,总的组数是可求的,那么只需求出乘积恰好等于的组的个数即可。
将n分为多个质数相乘的形式,对于每个质因数,可以知道中这个质数的指数,求出2*m个数相加等于这个指数的方案数即可。
有一个1~n的排列,每次可以从中删除一个最长上升子序列或最长下降子序列,请输出一种方案,在500次以内将序列删完。
直接每次nlogn找最长上升子序列或最长下降子序列,然后模拟删除即可……
甚至随便找点东西删(如lzlj同学的做法)都可以……
什么题啊……
求 的值。
数据范围:
这个数是黄金分割率,也就是方程的解,所以
,
那么,
,
...
所以
再找规律可以发现,,在n为奇数的时候恰好相等,n为偶数的时候右侧式子要减1。
矩阵快速幂求斐波那契即可。
给出和一个的矩阵,求一个 的排列x[i],满足,有。
数据范围:
如果矩阵合法,那么最小的那个数字(即数字1)在矩阵f中一定会呈现一个“十字形”,因为它和所有其他数字比较,都是它更小。删除这个十字后,原先第二小的数,就是剩余的当中最小的数,也符合这个规律。
最后必然出现下面这样的一个矩阵:
0 n
n 0
剩下没填的两位(就是矩阵中涉及的两位)一个是, 一个是。
所以要么-1,要么解的个数是2……
暴力
居然
能过
不想
说啥
给出一个十进制数和一个数,求满足以下条件的数的个数:
1. 不含前导0;
2. 各位数字颠倒顺序后可以变成n;
3. 是的倍数。
首先,思路肯定是……状压DP!
然鹅怎么状压呢?
根据我荒废近两个小时的思考,可以想象成一个每一位位权不同的多进制数,一共有10位,代表0~9的每个数字,每一位最大值就是n中这个数字出现的次数。这个数可以表示一个数中各个数字出现的次数情况。
例如,n中一共出现了1个“0”,2个“1”,1个“2”,那么要用到的状态有:
000, 001, 010, 011, 020, 021, 100, 101, 110, 111, 120, 121
对应的十进制数分别为0~11。
共2*3*2 = 12种状态。
那么怎么转移呢?
50分的做法是枚举填数的位置i、填的数字j、状态、模m的值。
然而正解根本不需要枚举填数位置,只需默认是最高位即可。
核心代码:
dp[0][0] = 1;
for(int i = 1; i < ri[0]; i++)
for(int j = 0; j <= 9; j++)
if(getnum(i, j))
g[i] = g[i - ri[j + 1]] + 1;
for(int i = 0; i < ri[0]; i++)
for(int j = (i == ri[0] - 1); j <= 9; j++)
if(getnum(i, j))
for(int k = 0; k < m; k++)
dp[i][k] = (dp[i][k] + dp[i - ri[j + 1]][((k - wei[g[i]]*j)%m + m)%m]) % P;