區間dp主要思想是先在小區間取得最優解,然後小區間合併時更新大區間的最優解。
基本**:
//51nod - 1021 石子歸併(區間dp)mst(dp,0) 初始化dp陣列
for(int i=1;i<=n;i++)
for(int len=2;len<=n;len++) //
區間長度
for(int i=1;i<=n;i++) //
列舉起點
}
【題目描述】
n堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將n堆石子合併成一堆的最小代價。
例如: 1 2 3 4,有不少合併方法
1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)
1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24)
1 2 3 4 => 1 2 7(7) => 3 7(10) => 10(20)
sample input
412sample output34
19預處理出區間和,然後列舉每個長度的區間和斷點,轉移即可。
f[i][j] = min(f[i][j], f[i][k]+f[k+1][j]+sum[j]-sum[i-1])
#include #includeview code#include
#include
#include
using
namespace
std;
typedef
long
long
ll;const
int maxn = 1000 + 100
;#define inf 0x3f3f3f3f
intmain()
for (int len = 2; len <= n; len++)
}printf(
"%d\n
", f[1
][n]);
}
uva - 10003 cutting sticks
題意:有一根長度為 n 的木棍,m 個可以切開的位置。
如果把乙個長木棍切成兩根短木棍,那麼花費就是那根長木棍的長度。
求把這根木棍按照 m 個切點全部切開的最小花費。
#include #includeview code#include
#include
#include
using
namespace
std;
#define maxn 100 + 100
#define inf 0x3f3f3f3f
intmain()
for (int len = 2; len <= m+1; len++)
for (int i = 0; i+len <= m+1; i++)
printf(
"the minimum cutting is %d.\n
", f[0][m+1
]); }
}
noip 2006 提高組 - 能量項鍊
有一串首位相連的環形能量珠項鍊,每個能量珠由頭部和尾部組成。相鄰的能量珠必定是某乙個的頭部 = 另乙個的尾部。
可以把兩個相鄰的能量珠(a,b)(b,c)合成乙個新的能量珠(a, c),並且釋放 a * b * c的能量。
操作這串能量珠能夠獲得的最大的總能量是多少?
樣例中,四個能量珠分別為(2, 3) (3, 5) (5, 10) (10, 2)
對於環形區間,我們只要把它展開成線形區間進行dp,然後取 dp[i, i+n-1] 中的最大值就可以了。
#include #includeview code#include
#include
using
namespace
std;
#define maxn 200 + 100
#define inf 0x3f3f3f3f
intmain()
a[2*n+1] = a[1
];
for (int i = 1; i <= 2*n; i++)
for (int j = i; j <= 2*n; j++)
f[i][j] = 0
;
for (int len = 2; len <= 2*n; len++)
for (int i = 1; i+len-1
<= 2*n; i++)
int ans = 0
;
for (int i = 1; i <= n; i++)
ans = max(ans, f[i][i+n-1
]); printf(
"%d\n
", ans);}}
hdu - 3506 monkey party
也是普通的環形區間dp,拆環為鏈。
然而這樣過不了的。因為資料範圍是2000,n^3的dp會tle。
所以需要用平行四邊形優化。
這個玩意我還沒有看懂,只是拿過來用。以後慢慢理解。
#include #includeview code#include
#include
using
namespace
std;
#define maxn 2000 + 100
#define inf 0x3f3f3f3f
intmain()
for (int i = 1; i <= 2*n; i++)
sum[i] = sum[i-1] +a[i];
for (int i = 1; i <= 2*n; i++)
for (int len = 2; len <= 2*n; len++)
for (int i = 1; i+len-1
<= 2*n; i++)}}
int ans =inf;
for (int i = 1; i <= n; i++)
ans = min(ans, f[i][i+n-1
]); printf(
"%d\n
", ans);}}
區間DP值入門題目 石子歸併
這兩天特別喪,不想學習,心態有點崩。不知道為什麼,可能是假期綜合症吧,又感覺自己處在了一種極度的迷茫之中,都怪袁老,讓我自己一天吃飽了沒事幹,胡思亂想,嗚嗚嗚.jpg。區間dp 區間dp就是在區間上的動態規劃,求解一段區間上的最優解,通過合併小區間的最優解來得到整個大區間上的最優解的演算法。時間複雜...
區間DP入門
區間dp,看名字其實會聯想到劃分dp,其實兩者的關係並不大。劃分dp是從頭到尾劃分解決,並且有劃分數量,而區間dp沒有這些限制條件,可以從任意區間開始,一直擴大到整個區間。不斷遞推求解。同樣也是分兩步去做。首先 還是進行資料處理,比如用陣列sum i j 去儲存i到j的和,或者是用別的方式處理並儲存...
區間DP入門
今天學長給我們講了區間dp,當然聽得雲裡霧裡,講完之後基本處於自閉狀態,然後還是自己到大佬的部落格,然後看部落格,但是並沒有找到很詳細的部落格,所以我想自己寫一寫,大神們勿噴哈.一 定義 區間dp,顧名思義是在區間上dp,它的主要思想就是先在小區間進行dp得到最優解,然後再利用小區間的最優解合併求大...