NOI1995 石子合併 DP 平行四邊形優化

2022-08-20 18:24:12 字數 1341 閱讀 1277

維護字首和,列舉分割點k

dp[i][j]表示第i到第j堆石子合併的最優值,sum[i][j]表示第i到第j堆石子的總數量。

平行四邊形優化

設m[i,j]表示動態規劃的狀態量。

m[i,j]有類似如下的狀態轉移方程:

m[i,j]=min(i≤k≤j)

定義s(i,j)為函式m(i,j)對應的使得m(i,j)取得最大值的k值。

我們可以證明,s[i,j-1]≤s[i,j]≤s[i+1,j]

那麼改變狀態轉移方程為:

m[i,j]=min(s[i,j-1]≤k≤s[i+1,j])

記錄最佳分割點point[i][j],k從point[i][j- 1]列舉到point[i + 1][j]即可

#include #include 

#include

#include

using

namespace

std;

typedef

long

long

ll;

ll pre[

110], s[110

];ll f[

110][110

];ll point[

110][110

];ll n;

ll get_min_score()}}

}return f[1

][n];}

intmain()

global_min =min(global_min, get_min_score());

swap(s[i], s[i + 1

]); }

printf(

"%lld\n

", global_min);

//system("pause");

return0;

}

問題 f: 石子合併(noi1995)

時間限制: 1 sec  記憶體限制: 128 mb

提交: 89  解決: 48

在操場上沿一直線排列著 n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆石子合併成新的一堆, 並將新的一堆石子數記為該次合併的得分。允許在第一次合併前對調一次相鄰兩堆石子的次序。

計算在上述條件下將n堆石子合併成一堆的最小得分和初次交換的位置。

輸入資料共有二行,其中,第1行是石子堆數n≤100;

第2行是順序排列的各堆石子數(≤20),每兩個數之間用空格分隔。

輸出合併的最小得分。

3 2 5 1

11

NOI1995 石子合併

在乙個園形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.圓的話就用2 n 1,即只有n種情況 include using namespace ...

NOI 1995 石子合併

合併石子的加強版 不過這可是95年的noi的題,準確說應該是合併石子是它的削弱版吧。環的處理就是在鏈的後面再來一遍鏈,然後列舉一下起點終點,就和合併石子一樣了。include include include include include define inf 0x3f3f3f3f using na...

NOI1995 石子合併

本來以為是一道簡單的區間dp問題,草草地寫了個程式結果樣例都沒過,仔細一看,原來n堆石子擺成了環。區間dp是線性dp的一種,寫法比較固定,一般是先列舉區間長度,再列舉區間左端點,推出區間右端點,狀態轉移通常是列舉中間點。這道題雖然成了環,但本質是不變的,還是從2到n列舉區間長度,只不過區間左端點可以...