被困沙漠岛 DP

【题目描述】
Larry的数学非常不好,他经常使用计算器。不幸的是,他现在和他一个好朋友被困在一个沙漠岛上。他们正试着通过解决一些好问题来消耗时间,而如果Larry 不能答出问题,Ryan就要吃掉他,所以他的命运掌握在你的手中!
这是一个很简单的问题:给出一个数字N,用K个小于等于N的数加起来为N,有多少张方法?
例如N = 20, K = 2,就有21中方法:
0+20
1+19
2+18
3+17
4+16
5+15
...
18+2
19+1
20+0
【输入格式】
输入文件desert.in中有若干组数据,对于每组数据一行两个整数N和K,直到N = K = 0时输入结束
【输出格式】
输出文件desert.out,对于每组数据,输出答案对1,000,000取模后的结果
【样例输入】
20 2
0 0
【样例输出】
21
【数据规模】
    对于30%的数据,1 <= N,K <= 10
对于60%的数据,1 <= N,K <= 50
对于100%的数据,1 <= N,K <= 100


 

开始看到这道题的时候,我大概懵逼了三分钟的时间,然后我就开始自己推,好不容易推出来了,结果循环变量打错了,还好运气好还拿了20分,下次要注意。

转移方程大概是这样的:

for(int i=3;i<=k;i++)
    for(int j=1;j<=n;j++)
      {
        for(int k=0;k<=j;k++)
          f[i][j]=(f[i][j]+f[i-1][j-k])%1000000;
      }

然后是全部代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int f[145][145];
int main()
{
  freopen("desert.in","r",stdin);
  freopen("desert.out","w",stdout);
  int n,k;
  while(scanf("%d%d",&n,&k))
    {
      if(!n&&!k)
    return 0;
      memset(f,0,sizeof(f));
      for(int i=0;i<=n;i++)
    {
      f[1][i]=1;
      f[2][i]=i+1;
    }
      for(int i=3;i<=k;i++)
    for(int j=1;j<=n;j++)
      {
        for(int k=0;k<=j;k++)
          f[i][j]=(f[i][j]+f[i-1][j-k])%1000000;
      }
      printf("%d\n",f[k][n]);
    }
}

 

posted @ 2017-08-28 17:21  GSHDYJZ  阅读(331)  评论(0编辑  收藏  举报