51nod 1043 幸运号码 (数位dp)
2017-09-02 20:06
232 查看
dp[i][j]表示 i 个数和为 j 的总数(包含0开头情况)
dp[i][j] = dp[i-1][j-k]
i & 1 :这里用滚动数组节省内存
非0开头的情况 * 0开头的情况:(dp[n&1][i]-dp[(n-1)&1][i]) *dp[n&1][i],最后将其累加即为结果。
开始没有想到这么做,还傻傻的dfs,用dp[1000][10]记录,今天心情不好,超级不好,做着做着放弃了。
#include<bits\stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int mod=1e9+7;
const int inf = 0x3f3f3f3f;
const int N = 1001;
int n;
long long dp[2][9*N];//i个数和为j的数量
int main(){
scanf("%d",&n);
memset(dp,0,sizeof(dp));
int sum;
for(int i = 0; i <= 9; ++i)
dp[1][i] = 1;
for(int i=2;i<=n;i++)
for(int j=0;j<=9*i;j++)
{
sum=0;
for(int k=0;k<=9;k++)
{if(j<k)break;
sum=sum+dp[(i-1)&1][j-k]%mod;
}
dp[i&1][j]=sum;
}
int ans=0;
for(int i=1;i<=9*n;i++)
ans = (ans + (dp[n&1][i]-dp[(n-1)&1][i]) *dp[n&1][i]) %mod;
printf("%d\n", ans);
return 0;
}
dp[i][j] = dp[i-1][j-k]
i & 1 :这里用滚动数组节省内存
非0开头的情况 * 0开头的情况:(dp[n&1][i]-dp[(n-1)&1][i]) *dp[n&1][i],最后将其累加即为结果。
开始没有想到这么做,还傻傻的dfs,用dp[1000][10]记录,今天心情不好,超级不好,做着做着放弃了。
#include<bits\stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int mod=1e9+7;
const int inf = 0x3f3f3f3f;
const int N = 1001;
int n;
long long dp[2][9*N];//i个数和为j的数量
int main(){
scanf("%d",&n);
memset(dp,0,sizeof(dp));
int sum;
for(int i = 0; i <= 9; ++i)
dp[1][i] = 1;
for(int i=2;i<=n;i++)
for(int j=0;j<=9*i;j++)
{
sum=0;
for(int k=0;k<=9;k++)
{if(j<k)break;
sum=sum+dp[(i-1)&1][j-k]%mod;
}
dp[i&1][j]=sum;
}
int ans=0;
for(int i=1;i<=9*n;i++)
ans = (ans + (dp[n&1][i]-dp[(n-1)&1][i]) *dp[n&1][i]) %mod;
printf("%d\n", ans);
return 0;
}
相关文章推荐
- 51nod 1043 幸运号码 数位dp
- 51Nod 1043 幸运号码 数位DP
- 51nod 1043 幸运号码 数位dp
- 51nod 1043 幸运号码(数位dp
- 【51Nod】1043 - 幸运号码(数位dp)
- 51nod 1043 幸运数字(数位dp)
- 51nod 1043 幸运号码【dp+滚动数组】
- 1043 幸运号码 数位DP
- 51 nod 1043 幸运号码(数位DP)
- 1043 幸运号码 数位dp
- 51nod oj 1043 幸运号码 【数位DP】
- 51nod 1043 幸运号码(dp)
- AC日记——幸运号码 51nod 1043
- 51nod 1043 幸运号码
- 51nod 1043 幸运号码
- 51NOD 1043 幸运号码
- 51Nod 1043 幸运号码
- 51Nod-1043-幸运号码
- 51nod 1043 数位dp
- 51nod:第K个幸运排列(数位dp & 逆康托展开)