例如:5分钱换为零钱,有以下4种换法:
1、5个1分
2、1个2分3个1分
3、2个2分1个1分
4、1个5分
(由于结果可能会很大,输出Mod 10^9 + 7的结果)
5
4
思路:就是不断的更新dp。
用1分钱,去满足1到n之间的钱数,可能种类为1.
用2分钱,去满足2到n之间的钱数,其中i可能种类为,dp[i] + dp[i-2]
在此,两个注意点,(1)为什么从2开始,因为1的话,他不能用2去组成,也就是说他的开始就是用多少钱,作为开始,低于他,没有办法用他去组成,浪费时间。
(2)为什么,是dp[i] + dp[i-2],因为你看啊,假设i = 5,他用2分钱组成的可能种类是不是以前1分钱的种类,加上dp[3]的种类。(因为3分加上2分就是5分钱,所以3分的种类,每一种加上2分钱,不都是5分钱吗?dp[3]+2=5)此时的每一个dp[i]代表着的就是1和2分钱组成的种类。每一个i代表着,要组成i分钱。每一个dp[i] = dp[i] + dp[i-b[j]],道理就是上面的解释。
代码如下:#include<iostream> #include<cstdio> using namespace std; int a[100005],dp[100005]; int main() { int b[]={1,2,5,10,20,50,100,200,500,1000,2000,5000,10000}; int n,i,j; cin>>n; dp[0]=1; for(j=0;j<13;j++) { for(i=b[j];i<=n;i++) dp[i]=( dp[i-b[j]] + dp[i] )%1000000007; } cout<<dp[n]<<endl; return 0; }