题解:P1541 [NOIP2010 提高组] 乌龟棋

不难的线性 DP。


考虑 fa,b,c,df_{a,b,c,d}fa,b,c,d 表示用了 aaa 张爬行 111 格的牌,bbb 张爬行 222 格的牌,以此类推。那么答案就是 fca,cb,cc,cdf_{ca,cb,cc,cd}fca,cb,cc,cd,其中这四个数分别是四种牌的数量。至于状态转移方程?也简单,从当前状态中任意删掉一张牌,然后在四种情况中取最大值即可。注意如果某种牌目前一张都没用,那么是不计算他的。整体方程较长,可以看代码。

时间复杂度为 O(n4)O(n^4)O(n4),而且最劣情况下运算量也大约是 n4256\dfrac{n^4}{256}256n4,实际上一般情况完全比最劣情况的运算量还要少,因此可以通过。

#include <bits/stdc++.h>
using namespace std;
int f[41][41][41][41];
int a[355];
int main() {
	int n,m; cin >> n >> m;
	int sa = 0,sb = 0,sc = 0,sd = 0;
	for(int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	for(int i = 1,x;i <= m;i++) {
		cin >> x;
		if(x == 1) sa++;
		if(x == 2) sb++;
		if(x == 3) sc++;
		if(x == 4) sd++;
	}
	f[0][0][0][0] = a[1];
	for(int i = 0;i <= sa;i++) {
		for(int j = 0;j <= sb;j++) {
			for(int k = 0;k <= sc;k++) {
				for(int l = 0;l <= sd;l++) {
					if(i) f[i][j][k][l] = max(f[i][j][k][l],f[i-1][j][k][l]+a[i+2*j+3*k+4*l+1]);
					if(j) f[i][j][k][l] = max(f[i][j][k][l],f[i][j-1][k][l]+a[i+2*j+3*k+4*l+1]);
					if(k) f[i][j][k][l] = max(f[i][j][k][l],f[i][j][k-1][l]+a[i+2*j+3*k+4*l+1]);
					if(l) f[i][j][k][l] = max(f[i][j][k][l],f[i][j][k][l-1]+a[i+2*j+3*k+4*l+1]);
				}
			}
		}
	}
	cout << f[sa][sb][sc][sd] << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值