P1541 [NOIP2010 提高组] 乌龟棋
P1541 [NOIP2010 提高组] 乌龟棋
一,解析
这道题应该是线性dp,而且是逆推
六要素
1,状态
f[i][j][k][p]是四种卡牌用的张数
2,阶段
阶段就是选了哪几张卡牌为阶段
3,决策
决策就是用哪张卡牌
4,阶状态转移方程
if(whq!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq-1][xjz][zky][lyj]+a[ysc]);
if(xjz!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq][xjz-1][zky][lyj]+a[ysc]);
if(zky!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq][xjz][zky-1][lyj]+a[ysc]);
if(lyj!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq][xjz][zky][lyj-1]+a[ysc]);
5,边界值
边界值要注意的就是 f要初始化
lft[0][0][0][0]=a[1];
6,目标值
直接lft[w[1]][w[2]][w[3]][w[4]]就行了
二,代码
#include<bits/stdc++.h>
using namespace std;
int a[355],w[125];
int lft[41][41][41][41];
int main(){
int n,m,fbi=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>fbi;
w[fbi]++;
}
lft[0][0][0][0]=a[1];//初始化
for(int whq=0;whq<=w[1];whq++){
for(int xjz=0;xjz<=w[2];xjz++){
for(int zky=0;zky<=w[3];zky++){
for(int lyj=0;lyj<=w[4];lyj++){
int ysc=1+whq+xjz*2+zky*3+lyj*4;//一共移动了几步
if(whq!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq-1][xjz][zky][lyj]+a[ysc]);
if(xjz!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq][xjz-1][zky][lyj]+a[ysc]);
if(zky!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq][xjz][zky-1][lyj]+a[ysc]);
if(lyj!=0) lft[whq][xjz][zky][lyj]=max(lft[whq][xjz][zky][lyj],lft[whq][xjz][zky][lyj-1]+a[ysc]);
}
}
}
}
cout<<lft[w[1]][w[2]][w[3]][w[4]];//全用上的情况
return 0;
}