zoukankan      html  css  js  c++  java
  • 被困沙漠岛 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
    ",f[k][n]);
        }
    }
    PEACE
  • 相关阅读:
    cf 427D Match & Catch 后缀数组
    cf 244c Checkposts 强连通分量
    NSPredicate的学习
    正则表达式
    NavigationBar &UINavigationItem& toolbar方法汇总
    区块股票数量
    吃什么
    selenium
    laravel5
    vim golang dev
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7444762.html
Copyright © 2011-2022 走看看