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;
}
posted @ 2024-09-23 10:24  sad_lin  阅读(12)  评论(0编辑  收藏  举报