P1388算式 區間dp入門

2021-09-25 10:58:36 字數 1208 閱讀 4540

題目描述

給出n個數字,不改變它們的相對位置,在中間加入k個乘號和n-k-1個加號,(括號隨便加)使最終結果盡量大。因為乘號和加號一共就是n-1個了,所以恰好每兩個相鄰數字之間都有乙個符號。例如:

n=5, k=2,5個數字分別為1、2、3、4、5,可以加成:

12(3+4+5)=24

1*(2+3)*(4+5)=45

(12+3)(4+5)=45

輸入輸出格式

輸入格式:

輸入檔案共有二行,第一行為兩個有空格隔開的整數,表示n和k,其中(2<=n<=15, 0<=k<=n-1)。第二行為 n個用空格隔開的數字(每個數字在0到9之間)。

輸出格式:

輸出檔案僅一行包含乙個整數,表示要求的最大的結果

最後的結果<=maxlongint

輸入輸出樣例

輸入樣例#1: 複製

5 21 2 3 4 5

輸出樣例#1: 複製

120solution

很明顯的區間dp,狀態設計有兩種,對應這兩種列舉順序。一種是f[i][j]表示考慮到第i個位置,放了j的乘號的最大值,這個不太好轉移

那設計狀態為f[i][j]表示放了i個乘號考慮到j個位置,轉移就是f[i

][j]

=max

(f[i

−1][

k]∗(

sum[

j]−s

um[k

])

k

j>

if[i][j]=max(f[i-1][k]*(sum[j]-sum[k]) ki

f[i][j

]=ma

x(f[

i−1]

[k]∗

(sum

[j]−

sum[

k])k

j>

i初始值就讓f[0

][i]

=sum

[i

]f[0][i]=sum[i]

f[0][i

]=su

m[i]

就可以了

code

const int n=20;

int a[n],sum[n];

int f[n][n];

int main()

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

}} cout

}

區間DP入門

區間dp,看名字其實會聯想到劃分dp,其實兩者的關係並不大。劃分dp是從頭到尾劃分解決,並且有劃分數量,而區間dp沒有這些限制條件,可以從任意區間開始,一直擴大到整個區間。不斷遞推求解。同樣也是分兩步去做。首先 還是進行資料處理,比如用陣列sum i j 去儲存i到j的和,或者是用別的方式處理並儲存...

區間DP入門

今天學長給我們講了區間dp,當然聽得雲裡霧裡,講完之後基本處於自閉狀態,然後還是自己到大佬的部落格,然後看部落格,但是並沒有找到很詳細的部落格,所以我想自己寫一寫,大神們勿噴哈.一 定義 區間dp,顧名思義是在區間上dp,它的主要思想就是先在小區間進行dp得到最優解,然後再利用小區間的最優解合併求大...

區間dp入門

區間dp就是區間上的dp,先算出小區間的最優解,再由小區間合併推出大區間的最優解。include include include includeusing namespace std const int inf 0x3f3f3f3f const int maxn 1010 int n int a m...