題目描述 description
乙個學校舉行拔河比賽,所有的人被分成了兩組,每個人必須(且只能夠)在其中的一組,要求兩個組的人數相差不能超過1,且兩個組內的所有人體重加起來盡可能地接近。
輸入描述 input description
資料的第1行是乙個n,表示參加拔河比賽的總人數,n<=100,接下來的n行表示第1到第n個人的體重,每個人的體重都是整數(1<=weight<=450)。
輸出描述 output description
包含兩個整數:分別是兩個組的所有人的體重和,用乙個空格隔開。注意如果這兩個數不相等,則請把小的放在前面輸出。
樣例輸入 sample input
3100
90200
樣例輸出 sample output
190 200
該貪心做法只過80分
#include#includeview code#include
#include
#include
using
namespace
std;
int n,w[200
],all;
int f[3],b[3
];int ans=1
;void dfs(int last ,int tot,int
sum)
if(tot*2>all) return
;
for(int i=last+1;i<=n;i++)
dfs(i,tot+w[i],sum+1);}
intmain()
for(int i=n;i>=1;i--)
if(b[!maxn] -b[maxn] >1
)
printf(
"%d %d
",f[!maxn],f[maxn]);
return0;
}
可以用隨機做法,隨機變換位置。但隨機性太大
#include#includeview code#include
#include
#include
#include
using
namespace
std;
int n,w[200
],all;
int f[3],b[3
];int ans1,ans2=999999
;void
qqq()
}int
main()
if(b[!maxn] -b[maxn] >1
)
if(f[maxn]-f[!maxn] <=ans2-ans1)
ans1=f[!maxn],ans2=f[maxn];
}printf(
"%d %d
",ans1,ans2);
return0;
}
dp是對的,可ac。
但為什麼能dp是對的那,這是因為這題中人的重量不超過450。
那就可以把解本身當作狀態的乙個參量,把最優解問題轉化為判定性問題,用遞推的方法求解。
兩種處理方法
#include#includeview code#include
#include
#include
using
namespace
std;
intn,s,mid;
int w[105
];bool dp[51][45000
];int
main()
printf(
"%d %d
",ans,s-ans);
return0;
}
#include#includeview code#include
#include
#include
using
namespace
std;
intn,s,mid;
int w[105
];bool dp[51][45000
];int
main()
printf(
"%d %d
",minn,s-minn);
return0;
}
CODEVS 1959 拔河比賽
原題鏈結 看臉的時候到了 隨機化!重複!dp的flag倒下了!夏天沒有西瓜!總之有非常看臉的隨機做法 也有非常靠譜的dp做法 dp是bool型 判斷前i個人裡選j個能不能達到k 隨機化 include include include include include include include i...
Codevs 1959 拔河比賽
有兩種做法 第一種 dp 不過這個dp比較難想,而且比較特別,解釋見 注釋。include include include include using namespace std int n,sum,k,a 105 bool f 105 45005 int main printf d d min a...
codevs1959 拔河比賽
題目大意 給定乙個有 n 個數的集合,將這 n 個數均分成兩堆,求差值最小是多少。題解 有關集合選數的問題,應該是揹包問題,同時要求均分可知,選出的物品數目也應該是揹包費用的乙個維度,因此這是乙個多維費用揹包問題。設狀態 dp i j k 表示考慮了前 i 個數字,已經選了 j 個數字,數字之和為 ...