本题是一个动态规划背包问题。
题目如下:
【问题描述】
高考结束啦!结束啦!高考结束第一天,大黑带着她的宠物——麻婆来到一个樱桃园,他们要来摘樱桃吃啦。
这时大黑对他的宠物麻婆说:“你想不想吃樱桃啊?”
麻婆兴奋地说:“好啊!”
大黑说:“好吧,你去摘吧,我掏钱!但是我只给你一定的时间,你必须在规定的时间内回到我面前,否则你摘的樱桃都要归我吃!”
麻婆思考了一会儿,最终答应了。
由于麻婆的数学太弱……他并不知道怎样才能在规定时间摘到最多的樱桃,但你是一个好心人,如果你帮助它,你的RP一定会暴涨的!
对于这个可以RP暴涨的机会,你一定不会错过的是不是?
由于麻婆不是机器人,所以它的体力并不是无限的,他不想摘很多的樱桃以至体力为0,而白白把樱桃让给大黑。樱桃园呈长方形,每棵樱桃树都有自己唯一的坐标,樱桃园左上角的樱桃树坐标是(1,1)。麻婆每次只能摘一棵樱桃树,每颗樱桃树都可以摘K次(对于同一棵樱桃树,每次采摘所得樱桃数目相同)。每次摘完后都要返回出发点即大黑的所在地(0,0)
麻婆每秒只能移动一个单位,每移动一个单位耗费体力1(只限上下左右移动,摘取不花费时间和体力)。
【输入】
第一行共四个数,为N,M,TI,A分别表示试验田的长和宽,大黑给麻婆的时间,和麻婆的体力。
下面一个N行M列的矩阵樱桃园。表示每次每棵樱桃树上能摘的樱桃数。
接下来N行M列的矩阵,表示每棵樱桃树最多可以采摘的次数K
【输出】
一个数:麻婆可以获得的最多的樱桃个数。
【输入输出样例】
4 4 13 20
10 0 0 0
0 0 10 0
0 0 10 0
0 0 0 0
1 0 0 0
0 0 2 0
0 0 4 00 0 0 0
输出:10
10<=30%<=50
10<=100%<=100
对于K,10<=100%<=100
保证结果在longint范围内
#include
#include
#include
#include
#include
#include
using namespace std;
int n,m,t,a;
int f[1000005],k(0);
int maps[105][105],kmaps[105][105],v[1000005],dis[1000005],maxx(0);
int main()
{
freopen("manor.in","r",stdin);
freopen("manor.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&t,&a);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&maps[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&kmaps[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(maps[i][j]!=0)
{
if((i+j)*2<=t)//把“超时”的点去掉
{
while(kmaps[i][j]>0)
{
k++;
v[k]=maps[i][j];
kmaps[i][j]--;
dis[k]=(i+j)*2;
}
}
}
}
}
for(int i=1;i<=k;i++)
{
for(int j=a;j>dis[i];j--)
f[j]=max(f[j],f[j-dis[i]]+v[i]);
}
for(int i=1;i<=k;i++)
maxx=max(f[i],maxx);
printf("%d\n",maxx);
return 0;
}
经过转化,可以转化成01背包(应该是吧,动态转移方程使用的01背包的,但我同学说是多重背包),这个题就过了!
本人的C++水平还不是很高,难免有错误和漏洞,请各位斧正!