【上海交大oj】赫萝的桃子(动态规划)

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。

提示:可以用递归或者动态规划解决,答案保证在int范围内。

 

刚开始一直想着找公式,但是失败了,主要就是吃桃子是没有顺序的。然后想动态规划,但是没想到状态转移方程,就是因为不懂如何解决重复计算的问题,看了别人的解法才豁然开朗。具体就是开一个二维数组,储存m天吃n个桃子的种类数,然后动归。考虑时实际只需要分两类,一种是吃法中至少有一天只吃一个桃子,实际上就是ways【m-1][n-1]的个数,因为即使是其它天吃一个桃子也是可以转化为第m天吃一个,因此等效的。还有一类就是每天吃的桃子个数都大于1个,那么就是ways[m][n-m],相当于所有每天吃的桃子都减一时的个数,这样就可以动态规划了。

代码:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(){
 5     int n,a,b;
 6 
 7     cin>>n;
 8     for (int k=0;k<n;++k){
 9         cin>>a>>b;
10         int ways[b+1][a+1]; 
11         //预处理
12         for (int i = 1;i <= b;i++) {
13             for (int j = 1;j < i;++j) ways[i][j] = 0;
14             ways[i][i] = 1;
15         }
16         for (int i = 1;i <= a;++i) ways[1][i] = 1;
17         
18         for (int i = 2;i <= b;++i) {
19             for (int j = i+1;j <= a;++j){
20                 ways[i][j] = ways[i-1][j-1] + ways[i][j-i];
21             }
22         }
23         cout<<ways[b][a]<<endl;
24     }
25     
26     return 0;
27 }
View Code

 

posted @ 2015-06-13 21:29  文_码  阅读(451)  评论(4编辑  收藏  举报