- 描述 小珂最近收集了些郵票,他想把其中的一些給他的好朋友小明。每張郵票上都有分值,他們想把這些郵票分成兩份,並且使這兩份郵票的分值和相差最小(就是小珂得到的郵票分值和與小明的差值最小),現在每張郵票的分值已經知道了,他們已經分好了,你知道最後他們得到的郵票分值和相差多少嗎?
- 輸入
- 第一行只有一個整數m(m<=1000),表示測試數據組數。
接下來有一個整數n(n<=1000),表示郵票的張數。
然後有n個整數Vi(Vi<=100),表示第i張郵票的分值。 - 輸出
- 輸出差值,每組輸出佔一行。
- 樣例輸入
-
2 5 2 6 5 8 9 3 2 1 5
- 樣例輸出
-
0 2
-
相同的套路,轉化爲01揹包問題。如果不能均分就儘量使兩堆重量/票價差距最小。可以想象成有一堆物品,兩個容器(容量和除以2),只要保證把其中一個容器的容積儘量加滿(當然恰好能滿最好),這就轉化成了0,1揹包問題了。
-
狀態轉移方程:dp[j] = max(dp[j],dp[j-weight[i]]+c[i]);
-
本題可以結合下一篇zb的生日http://blog.csdn.net/yjl1511/article/details/77365972
-
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[100005]; int a[1005]; int main() { int m,n,i,j; scanf("%d",&m); while(m--) { memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); scanf("%d",&n); int sum=0; for(i=1;i<=n;i++){ scanf("%d",&a[i]); sum+=a[i]; } int v=sum/2; for(i=1;i<=n;i++) for(j=v;j>=a[i];j--){ dp[j]=max(dp[j],dp[j-a[i]]+a[i]); } printf("%d\n",sum-2*dp[v]); } return 0; }
nyoj郵票分你一半
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.