码迷,mamicode.com
首页 > 编程语言 > 详细

【算法学习笔记】60.经典动态规划 SJTU OJ 1370 赫萝的桃子

时间:2015-06-10 23:55:39      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

 

Description

赫萝最喜欢吃蜂蜜腌渍的桃子。然而她能够得到的桃子有限,因此赫萝必须精打细算。赫萝在b天内可以得到a个桃子,每天赫萝至少吃一个桃子,她想知道她在a天内有多少种吃桃子的方法。吃桃子的顺序并不重要,也就是说赫萝认为“第一天吃一个桃子第二天吃两个桃子”和“第一天吃两个桃子第二天吃一个桃子”算一种方法。

Input Format

每个测试点有多组测试数据。

第一行一个数n,表示测试的数量。

接下来n行每行两个数a, b(a>b)。

Output Format

输出n行,每行一个数,表示方法数量。

Sample Input

2
7 3
6 2

Sample Output

4
3

HINTS AND LIMITS

对于70%的数据,a≤60,b≤15 。

对于100%的数据,a≤160,b≤40。

 

DP的原理不太好想,思路是这样的。

举一个例子。

比如 7 3

1 1 5

1 2 4

1 3 3

2 2 3

 

而 6 2

1 5 原型是 1 1 5

2 4 原型是 1 2 4

3 3 原型是 1 3 3

这里可以发现

dp[i][j] 和 dp[i-1][j-1] 有一个关系

 

再看 4 3

1 1 2 原型是 2 2 3 

发现 dp[i][j] 和 dp[i-j][j]也有关系

 

3+1 = 4 正好是结果

所以猜测

dp[i][j] = dp[i-j][j]  + dp[i-1][j-1]

 

分析一下可以 这个4的来源 分为两类

第一类  所有的都大于等于2的时候 等价于 每天减去1 的情况

第二类是 存在一个一天只吃1个桃子的情况 不能直接全减1 因为会出现0的情况 所以单独处理

      把这个天 去掉 dp[i-1][j-1]  //也许会担心那么其他的一天只有桃子的情况呢 这个不用怕 因为是从小到大的迭代过程 所以 已经内涵了

 

#include <iostream>
using namespace std;
int dp[300][50],n,k,i,j;
int main()
{
    int T;
    cin>>T;

    for(int k=0; k < T; ++k){

        int a,b;
        cin>>a>>b;
        dp[0][0] = 1;
        for (int i = 1; i <= a; ++i)
        {
            dp[i][1] = 1;
        } 
        for (int i = 1; i <= a ; ++i){//遍历桃子数

            for (int j=1; j <= b; ++j){//遍历天数

                if(i>=j)//必须桃子数大于等于天数 (因为每天至少一个桃子)
                    //分两种情况
                    //第一种情况 所有天都至少吃两个桃子 等价于 dp[i-j][j] j天每天吃一个之后的等效
                    //第二种情况 至少一天只吃一个桃子 所以把其中随便一天去掉 就是dp[i-1][j-1]
                    dp[i][j] = dp[i-j][j] + dp[i-1][j-1];
            }
        }
        cout<<dp[a][b]<<endl;
    }
    return 0;
}

 

【算法学习笔记】60.经典动态规划 SJTU OJ 1370 赫萝的桃子

标签:

原文地址:http://www.cnblogs.com/yuchenlin/p/sjtu_oj_1370.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!