前言
(其实是老师数据点太水了才能不开long long不开高精直接用DP过的,luogu测了才20分)
Description 题目描述
设有一个长度为n的数字字符串,分成k+1个部份,使其k+1部份相加的和为最大。例如:数字串’340670’,k=1,其加法有
3+40670=40673 34+0670=704 340+670=1010 3406+70=3476 34076+0=34076
其最大和为40676。
问题:当数字串和k给出后,找出一个分法使和为最大。
Input
第一行,n k
第二行,数字字符串
Output
最大的和
解法
用f[i][j]表示前i个数插进j个加号的最大值。
for(int v=1;v<=k;++v)
for(int i=v+1;i<=n;++i)
for(int j=v;j<i;++j)
a[i][v]=max(a[i][v],a[j][v-1]+l(j+1,i));
(变量很乱别介意)
v是插入的符号数;
i为边界,结束的位置;
j为分界,
求j前面插入v个符号的最大值+j后面的一个数(截止到i)
代码
#include<cstdio>
int a[42][8]={0},s[42]={0},n,k;
int l(int u,int b){ //求从u开始到b的数
int ans=0;
for(int i=u;i<=b;++i)
ans=ans*10+s[i];
return ans;
}
int max(int a,int b){
if(a>b) return a;
return b;
}
int main(){
scanf("%d%d\n",&n,&k);
char c;
for(int i=1;i<=n;++i){
scanf("%c",&c);
s[i]=c-48;
a[i][0]=a[i-1][0]*10+s[i]; //之前初始化的时候没有*10,WA了半天。。。
}
for(int v=1;v<=k;++v)
for(int i=v+1;i<=n;++i)
for(int j=v;j<i;++j)
a[i][v]=max(a[i][v],a[j][v-1]*l(j+1,i));
printf("%d",a[n][k]);
}