Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
Re:此题DP做法In Reply To:此题DP做法 Posted by:FOXLIU at 2008-09-21 01:00:16 > 题目要求n位数字前 (n/2) 位各位数字之和与后 (n/2) 位各位数字之和相等的数字的个数。 > 那就可以先求出 (n/2) 位的所有数字中,各位数字之和为 0、1、2、……、(n/2)*9 的数字的个数,再求出这些个数的平方和就可以了。 > > 假设用 num(i,j) 表示一共i位数字,各位数字之和为j的数字的个数 > 显然有: > num(1,0..9) = 1 > num(x,0) = 1 (x > 0) > 下面讨论 num(i,j) 的一般情况: > 首先约定用 D(i,j) 表示所有一共 i 位数字,各位和为 j 的数字所组成的集合。 > (1). > 由于 D(i-1,j) 里面的数字都是 (i-1) 位,和为 j ,那么可以对 D(i-1,j) 里面的每一个数字前面加个 0 作为首位,就可以得到 D(i,j) 中首位数字是0的所有数字。 > (2). > 由于 D(i,j-1) 里面的数字都是 i 位,和为 (j-1),那么可以对 D(i,j-1 )里面的每一个数字加个 1,就可以得到 D(i,j) 中的一些数字。 > 在(1)中求得了 D(i,j) 中首位数字是 0 的所有数字,但是, > D(i,j-1) 中也含有首位数字是 0 的数字,怎么办? > 只好把 1 也加到 D(i,j-1) 中所有首位数字是 0 的数字的首位上。也就是把首位的 0 变成 1。 > 可这样又产生了同样的问题: > D(i,j-1) 中也含有首位数字是 1 的数字,怎么办? > 只好把 1 也加到 D(i,j-1) 中所有首位数字是 1 的数字的首位上。也就是把首位的 1 变成 2。 > 以此类推,只要把 D(i,j-1) 中的每一个数字的首位都加上 1 即可。 > 至此,得到方程:num(i,j) = num(i-1,j) + num(i,j-1) > (3). > 此时又出现了新的问题: > 当 j-1>=9 时,原来 D(i,j-1) 中所有首位数字是 9 的数字怎么办?加了 1 就会进位,导致多了1位。 > 在(2)中,D(i,j-1) 中首位为 1-8 的数字进行了改造,得到了 D(i,j) 中首位数字是 1-9 的数字。 > 显然 D(i,j-1) 中首位数字是 9 的数字是多余的,要将其排除掉。 > 那么它的个数有多少呢? > 将这些数字的首位数字 9 去掉,那么剩下 (i-1) 位,其和为 (j-1-9) = (j-10)。 > 也就是说, D(i,j-1) 中首位数字是 9 的数字的个数有 num(i-1,j-10)个。 > > 综合以上3条,得到最终方程: > num(i,j) = num(i-1,j) + num(i,j-1) (j < 10) > num(i,j) = num(i-1,j) + num(i,j-1) - num(i-1,j-10) (j >= 10)#include<iostream> #include<algorithm> using namespace std; int main() { int n,dp[16][500],i,j,max; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); max=0; for(i=0;i<=9;i++) dp[1][i]=1; for(i=1;i<=15;i++) dp[i][0]=1; for(i=2;i<=n;i++) for(j=0;j<=9*n;j++) { if(j<10) dp[i][j]=dp[i-1][j]+dp[i][j-1]; else dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-10]; } cout<<dp[n][(n*9)/2]<<endl; } return 0; } 谢谢你的提示,下面是按照大牛的思路写的代码: Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator