51nod1101(dp)

Posted ygeloutingyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod1101(dp)相关的知识,希望对你有一定的参考价值。

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1101

 

题意:中文题诶~

 

思路:dp

我们用dp[i][j]存储前i中币值总价值为j的方法数,那么动态转移方程式为:

if(j>=gg[i]) //放的下第i中币值

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

else //放不下第i中币值

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

 

代码:

 1 #include <iostream>
 2 #define ll long long
 3 #define MAXN 100010
 4 using namespace std;
 5 
 6 const int mod=1e9+7;
 7 ll gg[]={0, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000};
 8 ll dp[15][MAXN]; //***dp[i][j]存储前i中币值总价值为j的方法数
 9 
10 int main(void){
11     int n;
12     cin >> n;
13     dp[0][0]=1;
14     for(int i=1; i<=13; i++){
15         for(int j=0; j<=n; j++){
16             if(j>=gg[i]){  //***放的下
17                 dp[i][j]=(dp[i-1][j]+dp[i][j-gg[i]])%mod;
18             }else{  //***放不下
19                 dp[i][j]=dp[i-1][j];
20             }
21         }
22     }
23     cout << dp[13][n] << endl;
24     return 0;
25 }

 

因为dp[i][]的情况都是由dp[i-1]得到的,所以我们可以直接用一维数组就好了~

 

代码:

 1 #include <iostream>
 2 #define ll long long
 3 #define MAXN 100010
 4 using namespace std;
 5 
 6 const int mod=1e9+7;
 7 ll gg[]={1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000};
 8 ll dp[MAXN];
 9 
10 int main(void){
11     int n;
12     cin >> n;
13     dp[0]=1;
14     for(int i=0; i<13; i++){ //***选用前i+1种币值
15         for(int j=gg[i]; j<=n; j++){ //***总价值为j的方法数
16             dp[j]=(dp[j]+dp[j-gg[i]])%mod;
17         }
18     }
19     cout << dp[n] << endl;
20     return 0;
21 }

 

以上是关于51nod1101(dp)的主要内容,如果未能解决你的问题,请参考以下文章

51 nod 1101 换零钱

51nod 1101 换零钱

区间dp 51nod1021

51Nod 1450 闯关游戏 —— 期望DP

51nod 1021 石子归并 (动态规划 简单代码)

51Nod 1042 数字0-9的数量(数位DP)