游戏智商 动规

游戏智商
时间限制: 1 Sec 内存限制: 128 MB

题目描述
熊的智商高还是猴子的智商高,这或许是一个很难考究的问题。故事里,吉吉国王一直标榜自己是最聪明最伟大的猴子国王,他的毛毛也是这么坚信。而我们的熊大和熊二却一直相信他们熊熊才是最聪明的。于是,在导游光头强的建议下,他们决定来一场 pk。
Pk 的内容是这样的,有 n 个格子,每个格子从左到右的编号依次是 1 到 n(编号也是位置),每个格子上都有不同美味值的水果(猴子们和熊们都很喜欢吃水果,所以水果对他们来说很有吸引力)。他们从位置 0 开始出发,手上有 AB 两种卡片,A 卡有 na 张,B 卡片有nb 张。每次他们可以用掉一张卡片,然后往前跳若干格,跳的格子数就是卡片上的数字。每跳到一个格子上,就可以吃掉对应格子里面的水果,获得水果的美味值。当然了,我们会保证当卡片用完的时候,一定刚好跳到第 n 个格子上。卡片一定要用完,不能有剩余。
游戏的结果就是在相同的情况下,谁能获得的水果美味值总和最大。熊熊们想要赢得这个比赛,于是熊二请求你的帮助。如果你可以帮助他算出最大值,他甚至可以把他最心爱的蜂蜜分享给你。
输入
输入第一行是3个整数n,na,nb,va,vb,n表示格子的总数,na表示A种卡片的数量,nb表示B种卡片的数量,va表示A种卡片上的数,vb表示B种卡片上的数。保证n一定等于nava+nbvb。
接下来n个整数,表示每个格子上水果的美味值,注意美味值有可能是负数。
输出
输出只有一行一个整数,表示卡片用完的时候,最多可以得到的美味值总和。
样例输入 Copy
3 1 1 2 1
1 2 3
样例输出 Copy
5
提示
共计有20个测试点。
对于第1-6个测试点,保证na=1,nb<=200,美味值都是小于等于10000的正整数。
对于第7-12个测试点,保证1<=na,nb<=12,美味值的绝对值小于等于10000。
对于100%的数据,保证1<=n<=20000,1<=na,nb<=2000,1<=va,vb<=5,va不等于vb,美味值的绝对值不超过1000000。

这个题看标签是记忆化搜索?结果我写的不好感觉能T掉,还是用动规吧。

f[i][j]表示选 a i 次 选 b j 次。
状态转移方程:
f [ i ][ j ] = max ( f [ i ][ j ],max(f [ i - 1 ][ j ],f [ i ][ j - 1 ])+a[pos]); pos=iva+jvb.

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#define X first
#define Y second
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

const int N=20020,M=2020,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n,na,nb,va,vb;
LL c[N],ans;
LL f[M][M];

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);
	
	cin>>n>>na>>nb>>va>>vb;
	
	for(int i=1;i<=n;i++)
		scanf("%lld",&c[i]);
	
	//初始化状态 
	for(int i=1;i<=nb;i++)
		f[0][i]=f[0][i-1]+c[i*vb];
	for(int i=1;i<=na;i++)
		f[i][0]=f[i-1][0]+c[i*va];

	for(int i=1;i<=na;i++)
		for(int j=1;j<=nb;j++)
		{
			int pos=i*va+j*vb;
			f[i][j]=max(f[i][j],max(f[i-1][j]+c[pos],f[i][j-1]+c[pos]));
		}

	cout<<f[na][nb]<<endl;



	return 0;
}










发布了43 篇原创文章 · 获赞 1 · 访问量 1563

猜你喜欢

转载自blog.csdn.net/DaNIelLAk/article/details/105406723