乌龟棋

洛咕

题意:一行N个格子,每个格子上有一个分数.从1出发,走到N.有M张卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片)每种类型的卡片上分别标有1,2,3,4四个数字之一,表示使用这种卡片后,将向前走相应的格子数.每张卡片只能使用一次.求最大总得分.

分析:设(f[i][j][k][l])表示有i张卡片1...l张卡片4,能获得的最大得分.初始化(f[0][0][0][0]=val[1])(从1号格出发,故一定能获得(val[1])分).

(x=i*1+j*2+k*3+l*4+1),即x是拥有该种情况下的卡片,最远能够到达的格子数.

如果(i>=1),(f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+val[x]))

(f[i-1][j][k][l])就是起点1到x之间的某一个格子的得分.可以理解为,我已经知道了起点和终点,然后在搞中间点.

其余三个以此类推.

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
int n,m;
int val[505],step[5],f[50][50][50][50];
int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++)val[i]=read();
    for(int i=1;i<=m;i++){
		int a=read();
		step[a]++;
    }
    f[0][0][0][0]=val[1];
    for(int i=0;i<=step[1];i++)//一定要从0开始,因为可以没有这种类型的卡片
		for(int j=0;j<=step[2];j++)
	    	for(int k=0;k<=step[3];k++)
				for(int l=0;l<=step[4];l++){
		    		int x=i+j*2+k*3+l*4+1;//一定要加1,因为是从1号格开始走的.
		    		if(i>=1)f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+val[x]);
		    		if(j>=1)f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]+val[x]);
		    		if(k>=1)f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]+val[x]);
		    		if(l>=1)f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]+val[x]);
		}
    printf("%d
",f[step[1]][step[2]][step[3]][step[4]]);
    return 0;
}

原文地址:https://www.cnblogs.com/PPXppx/p/10958898.html