Items divided

Items divided

题目链接:http://acm.xidian.edu.cn/problem.php?id=1183

参考:http://www.cnblogs.com/wanghetao/archive/2013/11/25/3442192.html

划分数(dp)

以前划分数没仔细看,拿到这题的时候随便弄了个dp,调了半个多小时,结束后游少提醒转移方程是错的= =

dp[i][j]表示将i划分成j个正整数的划分数,之后有以下三种情况:

1.i<j    此时i不可能划分成j个正整数,故dp[i][j]=0;

2.i==j  此时只有一种情况(将i划分成j个1),故dp[i][j]=1;

3.i>j    此时根据含不含1可分成(1和j-1个正整数)或 (j个不含1的正整数)

          即dp[i-1][j-1]或dp[i-j][j],故dp[i][j]=dp[i-1][j-1]+dp[i-j][j].

这题询问的次数有点多,直接求会TLE,所以我先打了张ans的表。

代码如下:

 1 #include<cstdio>
 2 #define N 1001
 3 #define Mod (long long)(1e9+7)
 4 using namespace std;
 5 typedef long long LL;
 6 LL n,m;
 7 LL dp[N][N];
 8 LL ans[N][N];
 9 int main(void){
10     for(int i=1;i<=1000;++i)dp[i][1]=1;
11     for(int j=2;j<=1000;++j)
12     for(int i=1;i<=1000;++i){
13         if(i==j)dp[i][j]=1;
14         else if(i>j)dp[i][j]=(dp[i-1][j-1]+dp[i-j][j])%Mod;
15     }
16     for(int i=1;i<=1000;++i)
17     for(int j=1;j<=1000;++j)
18         ans[i][j]=(ans[i][j-1]+dp[i][j])%Mod;
19     while(scanf("%lld%lld",&n,&m)){
20         if(n==0&&m==0)break;
21         printf("%lld\n",ans[n][m]);
22     }
23 }

 

posted @ 2016-08-24 16:21  barriery  阅读(170)  评论(0编辑  收藏  举报