洛谷$1541$ 乌龟棋 线性$DP$

Luogu   CH

 

Sol

f[i]表示走到第i个格子时获得的最大分数

发现转移与各个爬行卡片的数量有关,一共只有4种卡片

所以就把这四种卡片的已使用张数也放进状态,f[i][a][b][c][d]...

发现知道a,b,c,d后已得知i,所以减去i的一维,只剩下f[a][b][c][d]

综上,最终状态是f[a][b][c][d]表示1牌用了a张,2牌用了b张.....获得的最大分数

转移就枚举上一张用的是哪张牌转移即可

 

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 #define go(i,u,v) for(register int i=u;i<=v;i++)
 4 using namespace std;
 5 int read()
 6 {
 7   int x=0,y=1;char c=getchar();
 8   while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
 9   while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
10   return x*y;
11 }
12 int n,m,cd[5],sc[360],f[50][50][50][50];
13 int main()
14 {
15   n=read();m=read();
16   go(i,1,n) sc[i]=read();
17   go(i,1,m) {int x=read();cd[x]++;}
18   f[0][0][0][0]=sc[1];
19   go(a,0,cd[1]) go(b,0,cd[2])
20   go(c,0,cd[3]) go(d,0,cd[4]){
21     int x=a*1+b*2+c*3+d*4+1;
22     if(a>0) f[a][b][c][d]=max(f[a][b][c][d],f[a-1][b][c][d]+sc[x]);
23     if(b>0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b-1][c][d]+sc[x]);
24     if(c>0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c-1][d]+sc[x]);
25     if(d>0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c][d-1]+sc[x]);
26   }
27   printf("%d",f[cd[1]][cd[2]][cd[3]][cd[4]]);
28   return 0;
29 }
View Code

转载于:https://www.cnblogs.com/forward777/p/11009589.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值