题意:转化后为给定一个数L,问L拆成N个不同的数相加的方案数,其中N>=2。
解法:其实和上次做的分解的2的幂的数量相同,由于要求每个数都不相同,这里有一个非常好的观察角度,那就是观察一个数的分解中是否存在1,再加上考虑其能够被分解的数的个数即可建立递推关系。
设f[i][j]表示数 i 被分成 j 个不同的数相加的方案数,那么考虑最后分解中不含有1,那么这部分由f[i-j][j]得到,因为后者的每一个分解出来的数都加上1就行了;接着考虑分解中含有1,那么可以假定这个1就是最后分出来的,因为分解的顺序并不影响最后的结果,由于分解中数均不相同,扣除1后,就变成了f[i-1][j-1]中不含有1的情况了,而这个结果就又可以转化为:f[i-1-(j-1)][j-1]了。整个过程非常的巧妙。一个数最多分解成多少个数相加呢?这里可以假设L被连续的1+2+...+N组成,能够推算出一个上界出来。即求一个最大的x满足x*(x+1)/2 <= L。
直接开设状态会导致TLE,由于之多只和前300来层有关系,因此来个350的第一维来滚动吧。看到另外一种压缩方法是把第二维变成01,看来两者结合起来可以使得使用内存更加小。
代码如下:
#include#include #include #include #include #include using namespace std;int f[350][350]; // 50000的长度也最多拆成满足等式 x*(x+1)/2<=50000 的最大的x段 // 这题和上次的一道拆分成2的幂的题目非常的像了,从一个拆分中是否有1这个元素进行递推 int ans[50005];const int MOD = 1000000;int get(int x) { int k = (int)sqrt(2.0*x); while ((k+1)*(k+2)/2 <= x) k++; while (k*(k+1)/2 > x) k--; // 准确的计算出最多由多少个元素组成 return k;}void pre() { for (int cur = 0, i = 3; i <= 50000; ++i, cur = (cur+1) % 350) { int k = get(i); f[cur][2] = (i - 1) >> 1; ans[i] = f[cur][2]; for (int j = 3; j <= k; ++j) { // 至少由两部分组成 int nxt = (cur - j + 350) % 350; f[cur][j] = (f[nxt][j] + f[nxt][j-1]) % MOD; // 这个式子的含义是从不含1和含1两个状态合并并等价而来 ans[i] = (ans[i] + f[cur][j]) % MOD; } }}int main() { int T, N; pre(); scanf("%d", &T); while (T--) { scanf("%d", &N); printf("%d\n", ans[N]); } return 0;}
附(未取模):
i = 2, ret = 0
i = 3, ret = 1i = 4, ret = 1i = 5, ret = 2i = 6, ret = 3i = 7, ret = 4i = 8, ret = 5i = 9, ret = 7i = 10, ret = 9i = 11, ret = 11i = 12, ret = 14i = 13, ret = 17i = 14, ret = 21i = 15, ret = 26i = 16, ret = 31i = 17, ret = 37i = 18, ret = 45i = 19, ret = 53i = 20, ret = 63i = 21, ret = 75i = 22, ret = 88i = 23, ret = 103i = 24, ret = 121i = 25, ret = 141i = 26, ret = 164i = 27, ret = 191i = 28, ret = 221i = 29, ret = 255i = 30, ret = 295i = 31, ret = 339i = 32, ret = 389i = 33, ret = 447i = 34, ret = 511i = 35, ret = 584i = 36, ret = 667i = 37, ret = 759i = 38, ret = 863i = 39, ret = 981i = 40, ret = 1112i = 41, ret = 1259i = 42, ret = 1425i = 43, ret = 1609i = 44, ret = 1815i = 45, ret = 2047i = 46, ret = 2303i = 47, ret = 2589i = 48, ret = 2909i = 49, ret = 3263i = 50, ret = 3657i = 51, ret = 4096i = 52, ret = 4581i = 53, ret = 5119i = 54, ret = 5717i = 55, ret = 6377i = 56, ret = 7107i = 57, ret = 7916i = 58, ret = 8807i = 59, ret = 9791i = 60, ret = 10879i = 61, ret = 12075i = 62, ret = 13393i = 63, ret = 14847i = 64, ret = 16443i = 65, ret = 18199i = 66, ret = 20131i = 67, ret = 22249i = 68, ret = 24575i = 69, ret = 27129i = 70, ret = 29926i = 71, ret = 32991i = 72, ret = 36351i = 73, ret = 40025i = 74, ret = 44045i = 75, ret = 48445i = 76, ret = 53249i = 77, ret = 58498i = 78, ret = 64233i = 79, ret = 70487i = 80, ret = 77311i = 81, ret = 84755i = 82, ret = 92863i = 83, ret = 101697i = 84, ret = 111321i = 85, ret = 121791i = 86, ret = 133183i = 87, ret = 145577i = 88, ret = 159045i = 89, ret = 173681i = 90, ret = 189585i = 91, ret = 206847i = 92, ret = 225584i = 93, ret = 245919i = 94, ret = 267967i = 95, ret = 291873i = 96, ret = 317787i = 97, ret = 345855i = 98, ret = 376255i = 99, ret = 409173i = 100, ret = 444792i = 101, ret = 483329i = 102, ret = 525015i = 103, ret = 570077i = 104, ret = 618783i = 105, ret = 671417i = 106, ret = 728259i = 107, ret = 789639i = 108, ret = 855905i = 109, ret = 927405i = 110, ret = 1004543i = 111, ret = 1087743i = 112, ret = 1177437i = 113, ret = 1274117i = 114, ret = 1378303i = 115, ret = 1490527i = 116, ret = 1611387i = 117, ret = 1741520i = 118, ret = 1881577i = 119, ret = 2032289i = 120, ret = 2194431i = 121, ret = 2368799i = 122, ret = 2556283i = 123, ret = 2757825i = 124, ret = 2974399i = 125, ret = 3207085i = 126, ret = 3457026i = 127, ret = 3725409i = 128, ret = 4013543i = 129, ret = 4322815i = 130, ret = 4654669i = 131, ret = 5010687i = 132, ret = 5392549i = 133, ret = 5802007i = 134, ret = 6240973i = 135, ret = 6711479i = 136, ret = 7215643i = 137, ret = 7755775i = 138, ret = 8334325i = 139, ret = 8953855i = 140, ret = 9617149i = 141, ret = 10327155