Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

完全背包化为 0 1 背包思路

Posted by 11115122 at 2017-03-18 12:07:44 on Problem 1742
#include<iostream>
#include<vector>
using namespace std;
bool dp[100010];// 状态数组  dp[i]  表示可以组成价值i
int theUseOFcoins_i[100010];//  当执行到第i步时,第m个元素表示当前值使用 value[i]的数目
int GetResult(int value[], int NumOfCoin[], int N, int M)
{
	memset(dp, 0, sizeof(dp));
	//初始化为0
	dp[0] = true;// 0价值总可以组成
	int result = 0;
	for (int i = 1; i <= N; i++)
	{
		memset(theUseOFcoins_i, 0, sizeof(theUseOFcoins_i));
		//第i步将完成的工作:
		//  对于价值为 value[i-1] 的硬币,其个数为 NumOFCoin[i-1],将其视为不同的元素 (0 1背包)可以取,可以不取
		//根据之前的已经组成的价值,判断能否组成新的价值
		for (int j = value[i-1]; j <= M; j++)
		{
			//当满足 之前可以组成价值 j-value[i-1],且价值 j 没有组成,且之前组成价值i时使用的value[i-1] 的数目小于 theUseOFcoins[i-1]
			if (dp[j] == false && dp[j - value[i - 1]] == true && theUseOFcoins_i[j-value[i-1]] < NumOfCoin[i - 1])
			{
				//那么价值 j 可以组成,且组成价值 所使用的value[i-1] 类型硬币 +1
				dp[j] = true;
				result++;
				theUseOFcoins_i[j] = theUseOFcoins_i[j-value[i-1]] + 1;
			}
			//对于使用多个 value[i-1] 硬币,其在对应价值处的使用数目均被合理赋值为 0 1 2 ...
		}
	}
	return result;

}
int main()
{
	int N, M;
	vector<int> result;
	while (cin >> N >> M)
	{
		if (N == 0 && M == 0)
			break;
		int *value = new int[N];
		int *NumOFCoin = new int[N];
		for (int i = 0; i < N; i++)
			cin >> value[i];
		for (int j = 0; j < N; j++)
			cin >> NumOFCoin[j];
		result.push_back(GetResult(value, NumOFCoin, N, M));
		delete[]value;
		delete[]NumOFCoin;
	}
	for (int i = 0; i < result.size(); i++)
		cout << result[i] << endl;
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator