XDOJ-分配寶藏
阿新 • • 發佈:2020-12-27
————————————
隔了段時間,又開始發了。因為這個程式碼值得我記錄一下?
畢竟只有20行嘛(把註釋去掉後)。然後也是最近遇到了DFS和揹包的動態規劃的問題,頭有點禿。
然後今天沒做多久就寫出來了,我覺得最大的幫助,應該是來自B站上up主秒懂演算法的視訊“【動態規劃】揹包問題”,感覺非常清晰啦!
這題感覺是真的不難。
————————————
問題描述
兩個尋寶者找到一個寶藏,裡面包含n件物品,每件物品的價值分別是W[0],W[1],…W[n-1]。
SumA代表尋寶者A所獲物品價值總和,SumB代表尋寶者B所獲物品價值總和,請問怎麼分配才能使得兩人所獲物品價值總和差距最小,即兩人所獲物品價值總和之差的絕對值|SumA- SumB|最小。
輸入說明
輸入資料由兩行構成: 第一行為一個正整數n,表示物品個數,其中0<n<=200。
第二行有n個正整數,分別代表每件物品的價值W[i],其中0<W[i]<=200。
輸出說明
對於每組資料,輸出一個整數|SumA-SumB|,表示兩人所獲物品價值總和之差的最小值。
輸入樣例
4
1 2 3 4
輸出樣例
0
#include <stdio.h>
int dp[205][20005]={0};
int main(){
int v_w[205]={0};
int n,i,j,sum=0,sumA;
//輸入物品價值、容量、順便計算一下總價值
scanf("%d" ,&n);
for(i=1;i<=n;i++){
scanf("%d",&v_w[i]);
sum+=v_w[i];
}
for(i=1;i<=n;i++){//揹包的演算法
for(j=1;j<=(sum/2);j++){
if(v_w[i]>j)dp[i][j]=dp[i-1][j];
else dp[i][j]=(dp[i-1][j]>dp[i-1][j-v_w[i]]+v_w[i])?dp[i-1][j]:dp[i-1][j-v_w[i]]+v_w[i];
//printf("dp[%d][%d]:%d ",i,j,dp[i][j]);
}
// printf("\n");
}//這兩個printf語句我還保留在這裡,是因為它可以打印出非常整齊的表格(滑稽
if((sum-2*sumA)>0)printf("%d",(sum-2*dp[n][sum/2]));
else printf("%d",-(sum-2*dp[n][sum/2]));//絕對值問題
return 0;
}