HDU 4283:You Are the One(区间DP)
生活随笔
收集整理的這篇文章主要介紹了
HDU 4283:You Are the One(区间DP)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://acm.hdu.edu.cn/showproblem.php?pid=4283
題意:有n個數(shù)字,不操作的情況下從左到右按順序輸出,但是可以先讓前面的數(shù)字進(jìn)棧,讓后面的數(shù)字輸出,然后棧里的數(shù)字再輸出。執(zhí)行完各種操作后,第i個數(shù)字輸出的代價是w[i] * (i-1)。問如何弄才能使得代價最小,輸出。
思路:做了半個下午。好菜啊QAQ。
考慮兩種情況:
1、左區(qū)間的元素先輸出,然后右區(qū)間的元素再輸出。這個時候方程為 dp[i][j] = dp[i][k] + dp[k+1][j] + sum(k+1,j) * (i-k+1)。
2、左區(qū)間的元素進(jìn)棧,右區(qū)間的元素先輸出,然后左區(qū)間元素倒序輸出(因?yàn)檫M(jìn)了棧順序反了)。方程為 dp[i][j] = dp[k+1][j] + sum(i,k) * (j-k) + tmp.(tmp是倒序輸出的代價)
然后對于這兩種情況取優(yōu)就好了。
都是細(xì)節(jié)沒搞清楚才做好久。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define N 105 6 typedef long long LL; 7 LL dp[N][N], w[N], pre[N]; 8 9 int main() { 10 int t, cas = 0; 11 scanf("%d", &t); 12 while(t--) { 13 // char s[2]; 14 // if(cas == 0) scanf("%s", s); 15 int n; scanf("%d", &n); 16 memset(dp, 0x3f3f3f3f, sizeof(dp)); 17 for(int i = 1; i <= n; i++) scanf("%lld", &w[i]), dp[i][i] = 0; 18 for(int i = 1; i <= n; i++) pre[i] = pre[i-1] + w[i]; 19 for(int len = 1; len < n; len++) { 20 for(int i = 1; i + len <= n; i++) { 21 int j = i + len; 22 for(int k = i; k < j; k++) { 23 // a的情況是前后的區(qū)間都不入棧 24 LL a = dp[i][k] + dp[k+1][j] + (pre[j] - pre[k]) * (k + 1 - i); 25 LL tmp = 0; 26 for(int cnt = k; cnt >= i; cnt--) tmp += w[cnt] * (k - i); 27 // tmp 求倒著出棧的代價 28 // b的情況是前面的入棧,讓后面的區(qū)間直接出來 29 LL b = dp[k+1][j] + (pre[k] - pre[i-1]) * (j - k) + tmp; 30 dp[i][j] = min(dp[i][j], min(a, b)); 31 } 32 } 33 } 34 printf("Case #%d: %lld\n", ++cas, dp[1][n]); 35 } 36 return 0; 37 }?
轉(zhuǎn)載于:https://www.cnblogs.com/fightfordream/p/6475714.html
總結(jié)
以上是生活随笔為你收集整理的HDU 4283:You Are the One(区间DP)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从Qt4 迁移到Qt5 winEvent
- 下一篇: Tensorflow实现多元线性回归