動態規劃 最大的算式

2021-07-28 14:54:11 字數 1653 閱讀 1292

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

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

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

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

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

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

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

5 2 1 2 3 4 5

120

說明

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

分析:典型的動態規劃問題嘛。加號就是用來唬人的,因為加號和乘號總個數是n-1,可以保證每兩個數中間都一定有乙個運算子,所以只考慮乘號就可以了。用f[i][j]表示在前i個數中插入j個乘號所能達到的最大運算和,可以得到狀態轉移方程f[i][j]=max(f[i][j],f[i-l][j-1]*(sum[i]-sum[l-1]),其中2<=l<=i,sum陣列記錄的是前i個數的總和。初始值f[i][0]=sum[i],1<=i<=n。

#include

using namespace std;

int n,k;

long long f[120][120],sum[120];

int main()

for(int i=1;i<=n;i++)f[i][0]=sum[i];

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

printf("%lld\n",f[n][k]);

return 0;

}

另外一種有點小區別,在關於l取值的時候,上述的範圍在2<=l<=i, 下述的範圍在2<=l<=n.但是最後執行的結果都是相同的。

#include using namespace std;

#define max(a, b) a > b ? a : b;

long long int dp[16][16];

int sum[16];

int main()

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

for(int i = 2; i <= n; i++) }}

cout << dp[n][k];

return 0;

}

第三種方法如下,還不太懂。

第三種   提供了另外的一種思路

#include #include #define n 20

#define m_inf -999999

using namespace std;

int f[n][n][n]; //dp三維陣列

int sum[n][n]; //求i~j的總和

int arr[n]; //儲存數字

int n,m;

void reset() //清空陣列

int search(int s,int e,int k) //記憶化搜尋

}

動態規劃 最大的算式

問題描述 題目很簡單,給出n個數字,不改變它們的相對位置,在中間加入k個乘號和n k 1個加號,括號隨便加 使最終結果盡量大。因為乘號和加號一共就是n 1個了,所以恰好每兩個相鄰數字之間都有乙個符號。例如 n 5,k 2,5個數字分別為1 2 3 4 5,可以加成 1 2 3 4 5 24 1 2 ...

九 動態規劃 最大的算式

問題 最大的算式 問題描述 題目很簡單,給出n個數字,不改變它們的相對位置,在中間加入k個乘號和n k 1個加號,括號隨便加 使最終結果盡量大。因為乘號和加號一共就是n 1個了,所以恰好每兩個相鄰數字之間都有乙個符號。例如 n 5,k 2,5個數字分別為1 2 3 4 5,可以加成 1 2 3 4 ...

藍橋杯 最大的算式 動態規劃

問題描述 題目很簡單,給出n個數字,不改變它們的相對位置,在中間加入k個乘號和n k 1個加號,括號隨便加 使最終結果盡量大。因為乘號和加號一共就是n 1個了,所以恰好每兩個相鄰數字之間都有乙個符號。例如 n 5,k 2,5個數字分別為1 2 3 4 5,可以加成 1 2 3 4 5 24 1 2 ...