注意方案数类型和最优解类型的边界条件和转移状态方程。
#include
#include
using namespace std;
const int MOD = 1e9+7;
int dp[14][10001];//前i种货币换到j分钱的方案数量
int v[14]={0,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000};
int main(void)
{
int N;
cin>>N;
memset(dp,0,sizeof(dp));
for(int j=0;j<=N;j++) dp[0][j]= 0;//前0种货币换到非0分钱的方案是0
for(int i=0;i<=13;i++) dp[i][0]= 1;//任意种货币换到0分钱的方案是1
for(int i=1;i<=13;i++){
for(int j=1;j<=N;j++){
if(j-v[i]>=0){
dp[i][j]=(dp[i-1][j]+dp[i][j-v[i]])%MOD;
//理解:多重背包的本质就是允许反复选择同一种面值的钱,允许在第i种面值上反复选择
}
else{
dp[i][j]=dp[i-1][j]%MOD;
}
}
}
//for(int i=0;i<=13;i++){
// for(int j=0;j<=N;j++){
// cout<