《區間DP noip 2008 能量項鍊

2021-08-08 20:58:13 字數 2105 閱讀 7842

題目描述 description

在mars星球上,每個mars人都隨身佩帶著一串能量項鍊。在項鍊上有n顆能量珠。能量珠是一顆有頭標記與尾標記的珠子,這些標記對應著某個正整數。並且,對於相鄰的兩顆珠子,前一顆珠子的尾標記一定等於後一顆珠子的頭標記。因為只有這樣,通過吸盤(吸盤是mars人吸收能量的一種器官)的作用,這兩顆珠子才能聚合成一顆珠子,同時釋放出可以被吸盤吸收的能量。如果前一顆能量珠的頭標記為m,尾標記為r,後一顆能量珠的頭標記為r,尾標記為n,則聚合後釋放的能量為m*r*n(mars單位),新產生的珠子的頭標記為m,尾標記為n。需要時,mars人就用吸盤夾住相鄰的兩顆珠子,通過聚合得到能量,直到項鍊上只剩下一顆珠子為止。顯然,不同的聚合順序得到的總能量是不同的,請你設計乙個聚合順序,使一串項鍊釋放出的總能量最大。

例如:設n=4,4顆珠子的頭標記與尾標記依次為(2,3) (3,5) (5,10) (10,2)。我們用記號⊕表示兩顆珠子的聚合操作,(j⊕k)表示第j,k兩顆珠子聚合後所釋放的能量。則第4、1兩顆珠子聚合後釋放的能量為: (4⊕1)=10*2*3=60。

這一串項鍊可以得到最優值的乙個聚合順序所釋放的總能量為 ((4⊕1)⊕2)⊕3)=10*2*3+10*3*5+10*5*10=710。

輸入描述 input description

第一行是乙個正整數n(4≤n≤100),表示項鍊上珠子的個數。第二行是n個用空格隔開的正整數,所有的數均不超過1000。第i個數為第i顆珠子的頭標記(1≤i≤n),當i < n 時,第i顆珠子的尾標記應該等於第i+1顆珠子的頭標記。第n顆珠子的尾標記應該等於第1顆珠子的頭標記。

至於珠子的順序,你可以這樣確定:將項鍊放到桌面上,不要出現交叉,隨意指定第一顆珠子,然後按順時針方向確定其他珠子的順序。

輸出描述 output description

只有一行,是乙個正整數e(e≤2.1*109),為乙個最優聚合順序所釋放的總能量。

樣例輸入 sample input

4 2 3 5 10

樣例輸出 sample output

這道題很像石子歸併,同樣是列舉區間,需要注意幾個問題:

①列舉項鍊的斷開點時,區間長度一定是n而不是n+1

②我開的結構體,直接把區間複製了,所以一定要開兩倍空間,一開始開了100的,後來codevs說我wa(日常吐槽codevs),後來發現在windows下執行時是re

※※③列舉區間斷點時,這種轉移方法需要從左端點i到右端點的前一位j-1,為什麼呢?

比如我要求dp[3][5],分別是:(3 , 5)(5 , 10)(10 , 2),我的轉移方程是:dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+e[i].l * e[k].r * e[j].r)

第一種情況:從i+1列舉到j-1,那麼k只能等於4,也就是區間[3,4]和[5,5],但是有一種情況沒有列舉到,就是[3,3]和[4,5]

第二種情況:從i列舉到j,當k==j時,會出現區間[3,5]到區間[6,5],顯然不合法

所以我們在列舉k時,一定要從i列舉到j-1

**:

#include

#include

#include

using

namespace

std;

const

int maxn=200+10;

int n,ans;

int a[maxn];

int dp[maxn][maxn];

struct hh

e[maxn<<1];

int main()

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

} ans=max(ans,dp[l][r]);

}printf("%d",ans);

return

0;}

傳球遊戲(動態規劃dp NOIP2008)

傳球遊戲 總時間限制 1000ms 記憶體限制 65536kb 描述 上體育課的時候,小明的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。遊戲規則是這樣的 n個同學站成乙個圓圈,其中的乙個同學手裡拿著乙個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的乙個 ...

區間覆蓋 最少能覆蓋區間的區間數(貪心)

完整 部分易錯資料 大表哥分配 n 1 n 25,000 只中的一些奶牛在牛棚附近做些清潔。他總是要讓至少乙隻牛做清潔。他把一天分成t段 1 t 1,000,000 第一段是1,最後一段是t 每只奶牛只在一些時間段有空。奶牛如果選擇某一段時間,則必須完成整段時間的工作 你的任務是幫助fj安排一些奶牛...

區間dp HAOI2008 玩具取名

簡單的區間合併,因為最終結果的長度最多為4,所以dp設為3維,dp i j k 表示 i,j 區間內能否由k這個字母產生。include using namespace std typedef long long ll 三年競賽一場空,不開long long見祖宗 typedef int128 ll...