【代码随想录】零钱兑换II(关于组合与排列的区别)

题目描述

image

分析

按动态规划的分析步骤分析的话,代码是不难写出来的,但是写出来后你就会发现,结果不对,多出了很多组合:
image
image

解决方法:

image
什么都不用改,直接把两个循环调换即可。。

理解

如果把背包容量放外层,钱币放里层,则不同面值的钱币就是同时存在的,没有逻辑顺序,这样就会造成1 2 和2 1相互重复的情况,而把钱币放外层的话,就是先求出只有1的情况,再求出1 + 2的情况,再求出1 + 2 + 5的情况,这样就相当于规定了钱币的放入顺序。
代码如下:

#include<bits/stdc++.h>
using namespace std;

int change(int amount, vector<int>& coins) {
	int n = coins.size();
	vector<int> dp(amount+1, 0);
	dp[0] = 1;
	//int result = 0;
	
	for(int i = 0; i < n; i++){
		for(int j = 1; j <= amount; j++){
			if(j < coins[i]){
				continue;
			}else{
				if(dp[j - coins[i]] > 0){
					dp[j] += dp[j - coins[i]];
				}
			}
//			if(dp[j] == amount){
//				result++;
//			}
		}
	}
	for(int i = 0; i <= amount; i++){
		cout<<dp[i]<" ";
	}
	cout<<endl;
	return dp[amount];
}
int main(){
	int amount,n;
	cin>>amount>>n;
	vector<int> coins;
	int num;
	for(int i = 0; i < n; i++){
		cin>>num;
		coins.push_back(num);
	}
	cout<<change(amount, coins);
	return 0;
}
posted @ 2024-03-22 20:28  SaTsuki26681534  阅读(3)  评论(0编辑  收藏  举报