P1474货币系统

这是USACO的一道DP题,难度是提高—。

这道题是告诉我们货币种类,问你用这些货币组成一个面值最大有多少种方案。第一眼看上去想用dfs记忆化,随后发现其实这个题很类似于完全背包,可以取无线件,但是他的转移方程与普通的不同。而我一开始并没有静下心来去思考,没有想出来。最后得出了结论dp[j]=dp[j]+dp[j-coin[i]]。最后输出dp[T]即可。

1.认真推导状态转移方程,别老想着套用公式,必须举几个例子来推导出来,不要去畏惧困难,不要去怕麻烦

2.注意循环变量i于j别混淆,尤其是++

3.根据不同题意确定不同dp[]代表的含义

4.要对于dp[]进行初始化,比如这个题dp[0]=1;要考虑周全

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<algorithm>
#define N 1000001
#define ll long long
using namespace std;
int T,n;
int coin[N];
ll ans=0;
ll dp[N];//当前面额存在最大方案数 
int main(){
    cin>>n>>T;
    for(int i=1;i<=n;i++){
        scanf("%d",&coin[i]);
    }    
    dp[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=coin[i];j<=T;j++){
            dp[j]=dp[j]+dp[j-coin[i]];
        }
    }
    cout<<dp[T];
    return 0;
} 

 

posted @ 2019-07-25 22:17  毛炯人  阅读(206)  评论(0编辑  收藏  举报