CSU 1592 石子歸併 相鄰操作Dp問題

2021-07-02 05:24:52 字數 954 閱讀 9274

剛開始,想到的是貪心,每次合併相鄰和值最小的兩堆就行了,這題和poj 3186  treats for the cows以及紫書上的「最優矩陣鏈乘」差不多,初看看似貪心,實則是dp問題,但是都不會,呵呵。。。。只能看別人的**,然後再寫。。。

思路:用dp[i][j]表示合併區間[i,j]所需要的最小代價,那麼,狀態轉移方程為:dp[i][j]=max(dp[i]k]+dp[k+1][j]+sum[i][j]),i<=k<=j。顯然,對於我來講,這個式子是不好直接實現遞推的,但是發現這個遞推式子和紫書上的最優矩陣鏈乘差不多,都表示:要求大區間的解,得先知道小區間的解,所以,可以把上述狀態進行轉換一下:用dp[i][j]表示,以i為起點,長度為j的解,則狀態轉移方程變為:dp[i][j]=min(dp[i][j],dp[i][k]+dp[i+k+1][j-k-1]+sum[i][i+j]);這樣一來,就好實現遞推方程了。

**:#include#include#define maxn 110

#define inf 0x7fffffff

using namespace std;

int n,a[maxn],dp[maxn][maxn],sum[maxn];

int main(){

//freopen("in.txt","r",stdin);

int t;cin>>t;

while(t--){

cin>>n;

for(int i=1;i<=n;i++)

scanf("%d",a+i);

sum[0]=0;

for(int i=1;i<=n;i++)

sum[i]=sum[i-1]+a[i];

for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=inf;//初始化

for(int i=1;i<=n;i++) dp[i][0]=0;//初始化

for(int j=1;j

動態規劃 CSU 1592 石子歸併

題目 現在有n堆石子,第i堆有ai個石子。現在要把這些石子合併成一堆,每次只能合併相鄰兩個,每次合併的代價是兩堆石子的總石子數。求合併所有石子的最小代價。第一行包含乙個整數t t 50 表示資料組數。每組資料第一行包含乙個整數n 2 n 100 表示石子的堆數。第二行包含n個正整數ai ai 100...

CSU 1592 石子歸併 區間dp

現在有n堆石子,第i堆有ai個石子。現在要把這些石子合併成一堆,每次只能合併相鄰兩個,每次合併的代價是兩堆石子的總石子數。求合併所有石子的最小代價。第一行包含乙個整數t t 50 表示資料組數。每組資料第一行包含乙個整數n 2 n 100 表示石子的堆數。第二行包含n個正整數ai ai 100 表示...

石子歸併 CSU 1592 (區間合併)

題意 將n堆石子合併成一堆,每次只能合併相鄰的兩堆石子,每次合併的代價是兩堆石子總石子數和 思路 入門的一道區間dp,將合併區間由小向大推 dp i j 表示合併區間 i,j 的最小代價 初始化dp為inf,dp i i 0 dp i j min dp i k dp k 1 j sum i j i ...