题解:P1541 [NOIP2010 提高组] 乌龟棋
基础动态规划。
这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。
但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数组空间是
那么思路就明确了,我们设
转移的时候判断一下数组下标是否越界即可。
因为题目保证刚好用光所有卡片,那么如果设
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探