程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> uva562 - Dividing coins(01背包)

uva562 - Dividing coins(01背包)

編輯:C++入門知識

uva562 - Dividing coins(01背包)


題目:uva562 - Dividing coins(01背包)

 

題目大意:給出N個硬幣,每個硬幣有對應的面值。要求將這些硬幣分成兩部分,求這兩部分最小的差值。

 

解題思路:先求這些硬幣能夠湊出的錢(0, 1背包),然後再從sum(這些硬幣的總和)/2開始往下找這個值能否由這些硬幣湊出。要注意的是,可以由前n個硬幣組成那樣也是可以組成的面值。

 

代碼:

 

#include 
#include 

const int N = 105;
const int maxn = N * 500;

int v[N];
bool dp[maxn];
int n, sum;

void init () {

	memset (dp, false, sizeof (dp));
	dp[0] = true;

	for (int i = 0; i < n; i++)
		for (int j = sum; j >= v[i]; j--) {
				
			if (dp[j - v[i]])  
				dp[j] = true;
		//	dp[j] = dp[j - v[i]]; 這樣寫的話就否定了僅僅前面的i- 1個硬幣就組成j的情況。 
		}
}

int main () {

	int t;
	scanf (%d, &t);
	while (t--) {

		scanf (%d, &n);
		sum = 0;
		for (int i = 0; i < n; i++) {

			scanf (%d, &v[i]);
			sum += v[i];
		}
		
		init ();

		int i;
		for (i = sum / 2; i >= 0; i--) 
			if (dp[i])
				break;

		printf (%d
, sum - 2 * i);
				
	}
	return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved