揹包問題變種

0-1揹包:

n道數學題分值爲A[I]   A[2]  A[3].....A[N]   1<=A[i]<=100 

求怎麼拼湊得到100分,一共需要多少道題目,分別是哪些題目

輸入:3   10 30 60     輸出:3    1 2 3

int main(){
	int n = 0;

	while (cin >> n&&n>0){
		vector<int> score(n, 0);
		for (int i = 0; i < n; ++i){
			cin >> score[i];
		}
		vector<int> dp(101, -1);//存放的是當前分值下最後一次放入的題目的編號
		for (int i = 0; i < n; ++i){
			for (int j = 100; j >= score[i]; --j){
				if (j == score[i])
					dp[j] = i;
				else if (dp[j - score[i]] != -1){
					dp[j] = i;
				}
			}
		}

		int sum = 100;
		vector<int> result;
		while (dp[sum] != -1){//回溯得到所有題目的編號
			result.push_back(dp[sum]);
			sum -= score[dp[sum]];
		}
		cout << result.size() << endl;
		for (int i = result.size() - 1; i >= 0; --i){
			cout << result[i] + 1 << endl;
		}
	}
	return 0;
}

完全揹包:

當前有1毛錢,2毛錢,5毛錢,1塊錢問要得到10塊錢共有多少種不同的組合方案

int money(vector<int>& moneys,int total){
	vector<int> dp(total + 1, 0);//存放的是湊足j毛錢總共有幾種組合方法
	dp[0] = 1;
	for (int i = 0; i < moneys.size(); ++i){
		for (int j = moneys[i]; j <= total; ++j){
			dp[j] += dp[j - moneys[i]];//湊足j的方法是沒有考慮加入第i種面額的貨幣的方法數加上
                                       //考慮加入第i種面額的貨幣的方法數
		}
	}
	return dp[total];
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章