P1043 [NOIP2003 普及组] 数字游戏
又是一个思维毒瘤好题,但dp题都是这样,菜就多练吧。
拆环为链,前缀和加速计算,枚举断点数、起点、终点、断点。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=105;
int a[N*2];
int n,m;
int sum[N*2];
int mx[N][N][N];
int mi[N][N][N];
int modd(int x){
return ((x%10)+10)%10;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i+n]=a[i];
}
for(int i=1;i<=n*2;i++){
a[i]+=a[i-1];
}
for(int i=1;i<=2*n;i++){
for(int j=i;j<=2*n;j++){
mx[i][j][1]=mi[i][j][1]=modd(a[j]-a[i-1]);
}
}
for(int i=2;i<=m;i++){
for(int l=1;l<=2*n;l++){
for(int r=l+i-1;r<=2*n;r++){//每个断点占一个点
mi[l][r][i]=1e9;
}
}
}
for(int t=2;t<=m;t++){
for(int i=1;i<=2*n;i++){
for(int j=i+t-1;j<=2*n;j++){//和上面一样,断点占点,这没有就可以
for(int k=i;k<j;k++){//断点占点,这没有也行 (没有为0)
mi[i][j][t]=min(mi[i][j][t],mi[i][k][t-1]*modd(a[j]-a[k]));
mx[i][j][t]=max(mx[i][j][t],mx[i][k][t-1]*modd(a[j]-a[k]));
}
}
}
}
int ansx=0,ansm=1e9;
for(int i=1;i<=n;i++){//枚举区间
ansx=max(ansx,mx[i][i+n-1][m]);
ansm=min(ansm,mi[i][i+n-1][m]);
}
cout<<ansm<<"\n"<<ansx;
return 0;
}