您的位置:首页 > 其它

luogu1043【2003普及】数字游戏(区间dp)

2017-07-30 20:07 309 查看
在后面再复制一遍,把环变成链。dp[k][i][j]表示把i…j(包括i,j)分成m部分能获得的最值。状态数O(mn2),决策O(n),转移时间O(1),总的时间复杂度O(mn3)

#include <cstdio>
#include <cstring>
#include <iostream>
#define inf 1000000000
#define ll long long
using namespace std;
int const N=105;
int n,m,a
,sum

,fmin[10]

,fmax[10]

,ansmin=inf,ansmax=0;
int main(){
//  freopen("game.in","r",stdin);
//  freopen("game.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[n+i]=a[i];
}
for(int i=1;i<=n*2;i++)
for(int j=i;j<=n*2;j++){
sum[i][j]=(sum[i][j-1]+a[j])%10;
if(sum[i][j]<0) sum[i][j]+=10;
}
for(int i=1;i<=n<<1;i++)
for(int j=1;j<=n<<1;j++)
for(int k=1;k<=9;k++) fmin[k][i][j]=inf,fmax[k][i][j]=0;
for(int i=1;i<=n<<1;i++)
for(int j=i;j<=n<<1;j++) fmin[1][i][j]=fmax[1][i][j]=sum[i][j];
for(int k=2;k<=m;k++){
for(int i=1;i<=n<<1;i++)
for(int j=i;j<=n<<1;j++)
for(int p=i+k-1-1;p<=j-1;p++){
fmin[k][i][j]=min(fmin[k][i][j],fmin[k-1][i][p]*sum[p+1][j]);
fmax[k][i][j]=max(fmax[k][i][j],fmax[k-1][i][p]*sum[p+1][j]);
}
}
for(int i=1;i<=n;i++) ansmax=max(fmax[m][i][i+n-1],ansmax),ansmin=min(fmin[m][i][i+n-1],ansmin);
printf("%d\n%d",ansmin,ansmax);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: