郵票分你一半
來源:程序員人生 發(fā)布時(shí)間:2015-04-30 08:59:56 閱讀次數(shù):2801次
描寫
小珂最近搜集了些郵票,他想把其中的1些給他的好朋友小明。每張郵票上都有分值,他們想把這些郵票分成兩份,并且使這兩份郵票的分值和相差最小(就是小珂得到的郵票分值和與小明的差值最小),現(xiàn)在每張郵票的分值已知道了,他們已分好了,你知道最后他們得到的郵票分值和相差多少嗎?
-
輸入
- 第1行只有1個(gè)整數(shù)m(m<=1000),表示測(cè)試數(shù)據(jù)組數(shù)。
接下來有1個(gè)整數(shù)n(n<=1000),表示郵票的張數(shù)。
然后有n個(gè)整數(shù)Vi(Vi<=100),表示第i張郵票的分值。 -
輸出
- 輸出差值,每組輸出占1行。
-
樣例輸入
-
2
5
2 6 5 8 9
3
2 1 5
-
樣例輸出
-
0
2
這題乍1看像是摹擬或搜索,但是由于數(shù)量級(jí)和時(shí)間的限制,感覺會(huì)超時(shí),后來再仔細(xì)想一想,其實(shí)本質(zhì)就是0⑴背包問題。
我們將分值總和的1半作為總的時(shí)間, 郵票的價(jià)值既是價(jià)值又是花費(fèi)時(shí)間,所以這題就轉(zhuǎn)化為在固定時(shí)間取得的最大值。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 1005
int a[N];
int d[50005];
int n;
int main(){
int t, i, j;
scanf("%d", &t);
while (t--){
memset(d, 0, sizeof(d));
scanf("%d", &n);
int sum = 0;
for (i = 0; i < n; i++){
scanf("%d", &a[i]);
sum += a[i];
}
for (i = 0; i < n; i++){
for (j = sum / 2; j >= a[i]; j--){
d[j] = max(d[j], d[j - a[i]] + a[i]);
}
}
int res = (sum / 2 - d[sum / 2]) * 2;
if (sum % 2 != 0)
res++;
printf("%d
", res);
}
return 0;
}
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)