1、1043 幸运号码(数位DP)
题意:1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码。
例如:99、1230、123312是幸运号码。
给出一个N,求长度为2N的幸运号码的数量。由于数量很大,输出数量 Mod 10^9 + 7的结果即可。
思路:dp[i][j]:表示枚举到前i个数时总和为j的方案。可以由dp[i-1][k]递推。采用滚动数组处理,dp数组第一维大小可以缩至2.
1 #include<iostream> 2 #include<algorithm> 3 #include<memory.h> 4 #include<cstring> 5 using namespace std; 6 const int maxn = 1010; 7 const int MOD = 1e9 + 7; 8 long long dp[2][maxn * 9]; 9 int main() 10 { 11 int n; 12 while(~scanf("%d", &n)) 13 { 14 memset(dp, 0, sizeof(dp)); 15 dp[0][0] = 1;//避免n==1时讨论前导零 16 for (int i = 0; i <= 9; i++) dp[1][i] = 1; 17 for (int i = 2; i <= n; i++) 18 {//对于第i个数 19 for (int k = 0; k <= n * 9; k++) 20 {//和为k 21 dp[i % 2][k] = 0; 22 for (int j = 0; j <= min(k, 9); j++) 23 {//第i个数的取值 24 dp[i%2][k] = (dp[i%2][k]+dp[(i-1)%2][k - j]) % MOD; 25 } 26 } 27 } 28 long long ans = 0; 29 for (int i = 0; i <= n * 9; i++) 30 { 31 ans = (ans + dp[n % 2][i] * (dp[n % 2][i] - dp[(n - 1) % 2][i])) % MOD; 32 } 33 printf("%I64d ", ans); 34 } 35 return 0; 36 }