1. 程式人生 > >洛谷P1063 能量項鏈 區間動歸

洛谷P1063 能量項鏈 區間動歸

題目 color 不同 style code 斷點 cout ron names

題目描述

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

思路: 該題與石子合並相似。

轉移方程: f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+c[l]*c[k+1]*c[r+1]);

#include<iostream>
#include<cstdio>
using namespace std;
int n;
int a[500];
int f[500][500];
int main()
{
    cin >> n;
    for (int i=1;i<=n;i++)
    {
        cin >> a[i];
        a[i+n]=a[i];
    }
    
for (int i=2;i<2*n;i++)//枚舉區間大小 for (int l=1;l+i-1<2*n;l++)//枚舉左端點 { int r=l+i-1;//右端點 for (int k=l;k<r;k++)//枚舉區間斷點 f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+a[l]*a[k+1]*a[r+1]); } int ans=0; for (int i=1;i<=n;i++) ans
=max(ans,f[i][i+n-1]); cout << ans << endl; return 0; }

洛谷P1063 能量項鏈 區間動歸