【DP】洛谷 P1043 数字游戏

【分析】
典型的区间dp+环形问题处理,首先考虑线性情况的解法,以最大值为例:
f[i][j][k]表示i到j区间使用了k段的最优值
f[i][j][k] = max(f[i][l]+v[l+1][j]) { i+k-1<l<j }
线性能解决之后就直接断环为链,找所有的f[i][i+n-1]的最值就行了
【AC代码】

#include<cstdio>
#define maxn 139
#define INF 2147483647
using namespace std;
int n, m, f[maxn][maxn][39], v[maxn][maxn], a[maxn], maxx, minn = INF, g[maxn][maxn][39];
int max(int a, int b){return a>b?a:b;}
int min(int a, int b){return a<b?a:b;}
int main(){
	//freopen("1.in", "r", stdin);
	scanf("%d%d", &n, &m);
	for(int i = 1; i < n+1; i++){
		scanf("%d", a+i);
		a[n+i] = a[i];  //断环为链
	}
	for(int i = 1; i < (n<<1)+1; i++){
		for(int j = i; j < (n<<1)+1; j++)
			v[i][j] = ((v[i][j-1]+a[j])%10+10)%10;  //预处理部分
	}
	for(int i = (n<<1)-1; i > 0; i--)
		for(int j = i; j < (n<<1); j++)
			g[i][j][1] = f[i][j][1] = v[i][j];  //初始值部分

	for(int i = (n<<1)-1; i > 0; i--)
		for(int j = i; j < (n<<1); j++){
			for(int k = 2; k < m+1; k++){
				g[i][j][k] = INF;
				for(int l = i+k-1; l < j; l++){
					f[i][j][k] = max(f[i][j][k], f[i][l][k-1]*v[l+1][j]);
					g[i][j][k] = min(g[i][j][k], g[i][l][k-1]*v[l+1][j]);
				}
					
			}
		}
	for(int i = 1; i < n+1; i++)maxx = max(maxx, f[i][i+n-1][m]);
	for(int i = 1; i < n+1; i++)minn = min(minn, g[i][i+n-1][m]);
	printf("%d\n%d\n", minn, maxx);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值