专栏文章
题解:P1541 [NOIP2010 提高组] 乌龟棋
P1541题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqkn49l
- 此快照首次捕获于
- 2025/12/04 06:21 3 个月前
- 此快照最后确认于
- 2025/12/04 06:21 3 个月前
基础动态规划。
这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。
但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数组空间是 的,可以满足。
那么思路就明确了,我们设 表示四种卡片分别使用 张时所能获得的最大分数,然后用四重循环分别枚举四种卡片的使用数量,计算当前到达的位置 ,那么有转移方程:
转移的时候判断一下数组下标是否越界即可。
因为题目保证刚好用光所有卡片,那么如果设 表示数字为 的卡片的数量,答案显然为 。
Code
CPP#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;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...