1. 程式人生 > >luogu1541_烏龜棋_四維dp

luogu1541_烏龜棋_四維dp

題意

在這裡插入圖片描述

solution

  1. 我們發現四種卡牌每種的張數不超過40,所以4種都可以放進狀態裡,40^4=2560000,但是再把現在走到哪一位i放進狀態裡,就炸了
  2. 我們發現每種卡牌用了幾個,a,b,c,d,現在的位置=a1+b2+c3+d4+1
  3. 轉移
					if(a>0)f[a][b][c][d]=max(f[a][b][c][d],f[a-1][b][c][d]+s[1+pos]);
					if(b>0)f[a][b][c][d]=max(f[a][b][c][d],f[a][b-1][c][d]+s[1+pos]);
					if(c>0)f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c-1][d]+s[1+pos]);
					if(d>0)f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c][d-1]+s[1+pos]);

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<ctime>
#define pos a+2*b+3*c+4*d
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
inline int read(){
	char ch=' ';int f=1;int x=0;
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int f[50][50][50][50];
int s[400]; 
int main()
{
	int n=read(),m=read();
	int i,j;
	for(i=1;i<=n;i++)
	{
		s[i]=read();
	}
	int s1=0,s2=0,s3=0,s4=0;
	for(i=1;i<=m;i++)
	{
		int x=read();
		if(x==1) s1++;
		else if(x==2) s2++;
		else if(x==3) s3++;
		else s4++;
	}
	f[0][0][0][0]=s[1];
	for(int a=0;a<=s1;a++)
	{
		for(int b=0;b<=s2;b++)
		{
			for(int c=0;c<=s3;c++)
			{
				for(int d=0;d<=s4;d++)
				{
					if(a>0)f[a][b][c][d]=max(f[a][b][c][d],f[a-1][b][c][d]+s[1+pos]);
					if(b>0)f[a][b][c][d]=max(f[a][b][c][d],f[a][b-1][c][d]+s[1+pos]);
					if(c>0)f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c-1][d]+s[1+pos]);
					if(d>0)f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c][d-1]+s[1+pos]);
				}
			}
		}
	}
	cout<<f[s1][s2][s3][s4]<<endl;
	return 0;
}