寒假第六周 2.15 --- 2.21
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寒假第六周 2.15 --- 2.21相关的知识,希望对你有一定的参考价值。
新的一周^w^
2.15
hdu Greedy Tino
n个w[i],问能否分成相等的两堆,使得每一堆尽量大
不懂,题解说的是双塔dp
dp[i][j] 表示前i个搭成两个塔,差值为 j 的,这两个塔的高度的最大和
dp[i+1][j-v] = max(dp[i+1][j-v],dp[i][j]+v) //放在较高的那个塔上
dp[i+1][j+v] = max(dp[i+1][j+v],dp[i][j]+v)//放在较矮的那个塔
dp[i+1][j] = max(dp[i+1][j],dp[i][j]) 还可以不放
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int INF = (1<<30)-1; 9 const int maxn = 4005; 10 int n,w[maxn],dp[105][5005]; 11 int c; 12 13 void solve(){ 14 for(int i = 0;i < 105;i++){ 15 for(int j = 0;j < maxn;j++){ 16 dp[i][j] = -INF; 17 } 18 } 19 //sort(w+1,w+n+1); 20 dp[0][0] = 0; 21 for(int i = 0;i < n;i++){ 22 int v = w[i+1]; 23 for(int j = 0;j <= 4000;j++){ 24 if(dp[i+1][j+v] < dp[i][j]+v){ 25 dp[i+1][j+v] = dp[i][j]+v; 26 } 27 if(dp[i+1][abs(j-v)] < dp[i][j]+v){ 28 dp[i+1][abs(j-v)] = dp[i][j]+v; 29 } 30 if(dp[i+1][j] < dp[i][j]){ 31 dp[i+1][j] = dp[i][j]; 32 } 33 } 34 } 35 if(dp[n][0] == 0 && c == 0) puts("-1"); 36 else printf("%d\n",dp[n][0]/2); 37 } 38 39 int main(){ 40 int T; 41 scanf("%d",&T); 42 int kase = 0; 43 while(T--){ 44 scanf("%d",&n); 45 c = 0; 46 for(int i = 1;i <= n;i++) { 47 scanf("%d",&w[i]); 48 if(w[i] == 0) c++; 49 } 50 printf("Case %d: ",++kase); 51 solve(); 52 } 53 return 0; 54 }
搞不懂这种,和背包的那题,也是差值尽量小 的区别
明天再想>_<
以上是关于寒假第六周 2.15 --- 2.21的主要内容,如果未能解决你的问题,请参考以下文章