1个长度为2N的数,如果左边N个数的和 = 右边N个数的和,那么就是一个幸运号码。例如:99、1230、123312是幸运号码。给出一个N,求长度为2N的幸运号码的数量。由于数量很大,输出数量 Mod 10^9 + 7的结果即可。
题目解法:简单DP
设出数组dp【】【】,dp【i】【j】表示第i个数的和为j的个数
首先是最原始代码:
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <vector>
typedef long long LL;
using namespace std;
const int Maxn = 1005;
int table[Maxn][Maxn*9+100];//不带0的DP
int dp[Maxn][Maxn*9+100];//带0的DP
int n;
const int mod = 1e9 + 7;
int main(){
memset(table,0,sizeof(table));
memset(dp,0,sizeof(dp));
for(int i=1;i<=9;i++){
table[1][i] = 1;
dp[1][i] = 1;
}
dp[1][0] = 1;
for(int i=1;i<=1001;i++){
for(int j=0;j<=9*i;j++){
for(int k=0;k<=9;k++){
if(table[i+1][j+k]-mod>-table[i][j])
table[i+1][j+k] = table[i+1][j+k]-mod+table[i][j];
else
table[i+1][j+k]+=table[i][j];
table[i+1][j+k]%=mod;
if(dp[i+1][j+k]-mod>-table[i][j])
dp[i+1][j+k] = dp[i+1][j+k]-mod+dp[i][j];
else
dp[i+1][j+k]+= dp[i][j];
dp[i+1][j+k]%=mod;
}
}
}
while(~scanf("%d",&n)){
LL sum = 0;
int num = 0;
for(int i=1;i<=9*n;i++){
sum+=(LL)table[n][i]*(LL)(dp[n][i]);
sum%=mod;
//printf("%d. %d\n",i,table[n][i]);
}
printf("%lld\n",sum);
}
return 0;
}
这份代码问题很大,其中记录的数组有两个,显然不能设置成long long,否则会超出空间限制,那么就在计算的时候很小心,千万不能计算越界。这里说明个事情,这里是单组数据测试,如果是多组数据测试,我这份代码还是有优势的。
单组测试的有效数组就只有两个,一个带零的一个不带的,就声明两个就够了,进行其次不带零的数可以推出,例如DP【i】【j】不带零的结果就是DP【i】【j】带零的-DP【i-1】【j】带零的。
当然,下面的代码就是借鉴的大佬的了,写的非常不错。
typedef long long LL;
using namespace std;
const int Maxn = 1005;
int table[Maxn][Maxn*9+100];
int dp[Maxn][Maxn*9+100];
int n;
const int mod = 1e9 + 7;
int main(){
memset(table,0,sizeof(table));
memset(dp,0,sizeof(dp));
for(int i=1;i<=9;i++){
table[1][i] = 1;
dp[1][i] = 1;
}
dp[1][0] = 1;
for(int i=1;i<=1001;i++){
for(int j=0;j<=9*i;j++){
for(int k=0;k<=9;k++){
if(table[i+1][j+k]-mod>-table[i][j])
table[i+1][j+k] = table[i+1][j+k]-mod+table[i][j];
else
table[i+1][j+k]+=table[i][j];
table[i+1][j+k]%=mod;
if(dp[i+1][j+k]-mod>-table[i][j])
dp[i+1][j+k] = dp[i+1][j+k]-mod+dp[i][j];
else
dp[i+1][j+k]+= dp[i][j];
dp[i+1][j+k]%=mod;
}
}
}
while(~scanf("%d",&n)){
LL sum = 0;
int num = 0;
for(int i=1;i<=9*n;i++){
sum+=(LL)dp[n][i]*(LL)(dp[n][i]-dp[n-1][i]);
sum%=mod;
//printf("%d. %d\n",i,table[n][i]);
}
printf("%lld\n",sum);
}
return 0;
}