乌龟棋 dp

题目传送门

前言:本文思路参考是本人浏览博客看到的,写作时已忘记作者出处

思路:

1. 定义一个四维数组dp[i][j][k][l]表示用了一类卡i张,二类j张,三类k张,四类l张,所得到的最大分数。
2. 状态转移方程:dp[i][j][k][l] = max(dp[i-1][j][k][l] ,dp[i][j-1][k][l],dp[i][j][k-1][l],dp[i][j][k][l-1]) + a[i+j2+k3+l4+1],多加个1是因为包括起点在内

#include<iostream>
using namespace std;
const int N = 41;
int a[366]={
   0};
int b[121]={
   0};
int dp[N][N][N][N]={
   0};//dp[i][j][k][l]表示用了一类卡i张,二类j张,
					//三类kzhang,四类l张所得到的最大分数 
//dp[i][j][k][l] = max(dp[i-1][j][k][l] ,dp[i][j-1][k][l],
//dp[i][j][k-1][l],dp[i][j][k][l-1]) + a[i+j*2+k*3+l*4+1],多加个1是因为包括起点在内 
int main()
{
   
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
   
		cin>>a[i];
	} 
	for(int i=1;i<=m;i++)
	{
   
		int card;
		cin>>card;
		b[card]++; 
	 	//cin>>b[i];
	}
	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 l=0;l<=b[4];l++)
				{
   
					int x = i+j*2+k*3+l*4+1;
					if(i)  dp[i][j][k][l] = max(dp[i][j][k][l],dp[i-1][j][k][l] + a[x]);
					if(j) dp[i][j][k][l] = max(dp[i][j][k][l],dp[i][j-1][k][l]+a[x]);
					if(k) dp[i][j][k][l] = max(dp[i][j][k][l],dp[i][j][k-1][l]+a[x]);
					if(l) dp[i][j][k][l] = max(dp[i][j][k][l],dp[i][j][k][l-1]+a[x]);
					//这四个if相当于
					/* dp[i][j][k][l] = max(dp[i-1][j][k][l] ,dp[i][j-1][k][l], dp[i][j][k-1][l],dp[i][j][k][l-1]) + a[i+j*2+k*3+l*4+1],多加个1是因为包括起点在内 */ 
				}
			}
		}
	}
	cout<<dp[b[1]][b[2]][b[3]][b[4]]<<endl;
	return 0;
} 
全部评论

相关推荐

投递腾讯云智研发等公司9个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务