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

基础动态规划。

这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。

但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数组空间是 4042e6 的,可以满足。

那么思路就明确了,我们设 dpi,j,k,c 表示四种卡片分别使用 i,j,k,c 张时所能获得的最大分数,然后用四重循环分别枚举四种卡片的使用数量,计算当前到达的位置 x,那么有转移方程:

dpi,j,k,c=max(dpi1,j,k,c,dpi,j1,k,c,dpi,j,k1,cdpi,j,k,c1)+ax

转移的时候判断一下数组下标是否越界即可。

因为题目保证刚好用光所有卡片,那么如果设 fi 表示数字为 i 的卡片的数量,答案显然为 dpf1,f2,f3,f4

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read()
{
	int w=1,s=0;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+(ch-'0');ch=getchar();}
	return w*s;
}
const int mod=998244353;
const int maxn=400;
const int inf=2e9+10;
const double eps=1e-10;
int n,m,a[maxn],b[5];
int dp[42][42][42][42];
signed main(){
#ifdef Lydic
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
#endif
	cin>>n>>m;
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=m;i++)b[read()]++;
	dp[0][0][0][0]=a[1];
	for(int i=0;i<=b[1];i++){
		for(int j=0;j<=b[2];j++){
			for(int k=0;k<=b[3];k++){
				for(int c=0;c<=b[4];c++){
					int x=1+i+j*2+k*3+c*4;
					if(i)dp[i][j][k][c]=max(dp[i][j][k][c],dp[i-1][j][k][c]+a[x]);
					if(j)dp[i][j][k][c]=max(dp[i][j][k][c],dp[i][j-1][k][c]+a[x]);
					if(k)dp[i][j][k][c]=max(dp[i][j][k][c],dp[i][j][k-1][c]+a[x]);
					if(c)dp[i][j][k][c]=max(dp[i][j][k][c],dp[i][j][k][c-1]+a[x]);
				}
			}
		}
	}
	cout<<dp[b[1]][b[2]][b[3]][b[4]];
	return 0;
}

posted @   Redamancy_Lydic  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示