P1026 题目大意:求x1+x2+……xr=n解的个数(其中x1,x2,……xr为互异的正整数,r>=2)
解法一:把1,2,3……n-1作为n-1个物品,0/1背包即可
解法二:f[i][j]为共i块砖,其中第一列(最小一列摆j块)的方案数代码
代码_1:
f[i][j]=sum{f[i-j,k]} (j<i;j+1<=k<=i);边界 f[i][i]=1; (1<=i<=i-1);
代码_2:在_1的基础上时间优化,但编程复杂度增加
考虑到f[i][j]=0;(j>i/2若i为奇数;j>=i/2若i为偶数)且f[i][i]=1; (1<=i<=i-1);
可修改j,k的上限
代码_3:在_2的基础上的小优化 (x-1)/2避免对x奇偶的讨论
引用:http://blog.csdn.net/jcwkyl/article/details/3016830
启示:看题解尽量先不看题解代码,如若看题解代码看不懂时大可以先按照思路自己编,然后对比。
(就像这题看了题解一开始很纠结/2的问题,不知不觉优化到了题解一样)
_1:
for (i=1;i<n;i++) f[i][i]=1;
for (i=3;i<=n;i++)
for (j=1;j<i;j++)
for (k=j+1;k<=i-j;k++)
f[i][j]+=f[i-j][k];
_2:
for (i=1;i<n;i++) f[i][i]=1;
for (i=3;i<=n;i++)
for (j=1;j<=i/2;j++)
{ for (k=j+1;k<=(i-j)/2;k++)
f[i][j]+=f[i-j][k];
if (j!=2*i) f[i][j]++;
}
_3:
for (i=1;i<n;i++) f[i][i]=1;
for (i=3;i<=n;i++)
for (j=1;j<=(i-1)/2;j++)
{ for (k=j+1;k<=(i-j-1)/2;k++)
f[i][j]+=f[i-j][k];
f[i][j]++;
}