乘積最大(dp)
阿新 • • 發佈:2020-09-19
連結:https://ac.nowcoder.com/acm/contest/1071/A?&headNav=acm
來源:牛客網
設有一個長度為N的數字串,要求選手使用K個乘號將它分成K+1個部分,找出一種分法,使得這K+1個部分的乘積能夠為最大。
同時,為了幫助選手能夠正確理解題意,主持人還舉了如下的一個例子:
1) 3*12=36
2) 31*2=62
這時,符合題目要求的結果是:31*2=62
現在,請你幫助你的好朋友XZ設計一個程式,求得正確的答案。
輸入描述:
第一行共有2個自然數N,K(6 ≤ N ≤ 40,1 ≤ K ≤ 6)
第二行是一個長度為N的數字串。
輸出描述:
輸出所求得的最大乘積(一個自然數)。示例1
輸入
複製4 2 1231
輸出
複製62
dp[i][j]就是第i個數字後加入j個最大值
a[i][j]就是i到j組成的數字
dp[i][j]=max(dp[i][j],dp[l][j-1]*a[l+1][i]);//l=1到i
#include<iostream> #include<algorithm> #include<map> #include<string> #include <math.h> #include<memory.h> #include<cstring> #include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int INF=0x3f3f3f3f; const int maxn=100; ll dp[maxn][maxn];//dp[i][j]就是第i個數字後加入j個最大值 ll a[maxn][maxn];//a[i][j]就是i到j組成的數字 char p[maxn]; int main(){ int n,k; cin>>n>>k; scanf("%s",p+1); int len=strlen(p+1); for(int i=1;i<=len;i++){ for(int j=i;j<=len;j++){ a[i][j]=a[i][j-1]*10+p[j]-'0'; } } for(int i=1;i<=len;i++){ dp[i][0]=a[1][i]; } for(int j=1;j<=k;j++){ for(int i=2;i<=len;i++){ for(int l=1;l<i;l++){ dp[i][j]=max(dp[i][j],dp[l][j-1]*a[l+1][i]); } } } cout<<dp[n][k]<<endl; }