URAL1036 Lucky Tickets
题意:
给出一个数字n,每张票有2n位数字,当某张票的前n位数字的和等于后n位数字的时候,我们称这张票是幸运的
现在给出所有位的和,请计算符合这个和的幸运票的数量
分析:
显然当S是奇数的时候,方案数为0。
当S是偶数,把S/2只计算一边,最后平方一下。
我们令dp[i][j]是长度为i,和为j的方案数。这里的转移可以考虑阶段,i就是阶段。每个状态肯定是从上一个阶段中转移过来的。
显然每一位的数字是0到9,所以每增加一位的时候,和增加0到9
那么状态转移方程就很显然了
dp[i][j]=sum(dp[i-1][j-k])。其中k<=min(j,9)
代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 6 using namespace std; 7 const int maxn=50+10; 8 int n,s; 9 long long dp[maxn][maxn]; 10 int main(){ 11 scanf("%d%d",&n,&s); 12 if(s%2){ 13 printf("0"); 14 return 0; 15 } 16 s/=2; 17 memset(dp,0,sizeof(dp)); 18 dp[0][0]=1; 19 20 for(int i=1;i<=n;i++){ 21 for(int j=0;j<=s;j++){ 22 for(int k=0;k<=min(j,9);k++){ 23 dp[i][j]+=dp[i-1][j-k]; 24 } 25 } 26 } 27 long long ans=dp[n][s]*dp[n][s]; 28 cout<<ans; 29 return 0; 30 }
但是别激动!这份代码是没法AC的!因为答案太大了,long long 开不下(其实我这个题在场上一直WA,根本没想到要高精度),所以要写高精度才能通过!高精度的JAVA代码等明天队友写完给我我再贴上~