1041 [NOIP2010]乌龟棋 动态规划 递推
分析
看数据范围,4种爬行卡片,每种卡片的张数不会超过40,这个条件很重要,很容易想到用动态规划解决
- dp[i][j][k][l] 表示使用了 i张1卡,j张2卡,k张3卡,l张4卡得到的最优值
那么有转移方程
- dp[i][j][k][l] = max(dp[i - 1][j][k][l] + a[val], dp[i][j - 1][k][l] + a[val], dp[i][j][k - 1][l] + a[val] + dp[i][j][k][l - 1] + a[val]), 其中 val为 i + 2 * j + 3 * k + 4 * l
这题已经到我知识盲区了,我还在想有四种变量,我在想线性DP,一张卡一张卡使用,他直接大手一挥把四种卡一起用,应该属于递推吧
//-------------------------代码----------------------------
//#define int LL
const int N = 2e5+10;
int n,m;
int a[N],b[N],num[N];
int dp[50][50][50][50];
void solve()
{
cin>>n>>m;
fo(i,1,n) cin>>a[i];
fo(i,1,m) {
int x;cin>>x;
num[x] ++ ;
}
dp[0][0][0][0] = a[1];
fo(i,0,num[1]) {
fo(j,0,num[2]) {
fo(k,0,num[3]) {
fo(l,0,num[4]) {
int val = a[i + 2 * j + 3 * k + 4 * l + 1];
if(i) {
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i - 1][j][k][l] + val);
}
if(j) {
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j - 1][k][l] + val);
}
if(k) {
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j][k - 1][l] + val);
}
if(l) {
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j][k][l - 1] + val);
}
}
}
}
}
cout << dp[num[1]][num[2]][num[3]][num[4]] << "\n";
}
signed main(){
clapping();TLE;
// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}
/*样例区
*/
//------------------------------------------------------------