讨论 / 二维KnapSack,就60
飞雪天涯 2008-11-09 00:38:00
点我顶贴 收藏 删除
/*

比赛(Test):查看题目 Show Problem

赛题题目:科技庄园

所属比赛:第一届AC-XL杯NOIP08提高模拟赛

问题编号:381 [提交该赛题]

描述: Life是河北衡水中学的学生,他是一个道德极高的学生,他积极贯彻党的十七大精神,积极走可持续发展道路,

在他的不屑努力下校领导终于决定让他在衡中的一片闲杂地里种桃,以亲身实践种田的乐趣,厉行节约,告诉人们节约

的重要性!

春华秋实,在这个金秋的季节,Life带者他的宠物——PFT到了他的试验田,当他看见自己的辛勤成果时,心里是那个高

兴啊!

这时Life对他的宠物PFT说:“你想不想吃桃啊?”

PFT兴奋的说:“好啊!”

Life说:“好吧,但是我只给你一定的时间,你必须在规定的时间之内回到我面前,否则你摘的桃都要归我吃!”

PFT思考了一会,最终答应了!

由于PFT的数学不好!它并不知道怎样才能在规定的时间获得最大的价值,但你是一个好心人,如果你帮助它,你的RP一

定会暴涨的!

对于这个可以RP暴涨机会,你一定不会错过的是不是?

由于PFT不是机器人,所以他的体力并不是无限的,他不想摘很多的桃以至体力为0,而白白把桃给Life。同时PFT每次只

能摘一棵桃树,摘桃花费时间体力,每棵桃树都可以摘K次(对于同一棵桃每次摘的桃数相同)。每次摘完后都要返回出

发点(PFT一次拿不了很多)即Life的所在地(0,0){试验田左上角的桃坐标是(1,1)}。

PFT每秒只能移动一个单位,每移动一个单位耗费体力1(摘取不花费时间和体力,但只限上下左右移动)。

【样例解释】

可以摘到1次(1,1)和1次(2,3),体力和时间不满足再摘桃了。

【数据范围】

对于M N TI A

10<=30%<=50

10<=100%<=100

对于K

10<=100%<=100

保证结果在longint范围内

输入格式: 第一行:四个数为N,M,TI,A 分别表示试验田的长和宽,Life给PFT的时间,和PFT的体力。

下面一个N行M列的矩阵桃田。表示每次每棵桃树上能摘的桃数。

接下来N行M列的矩阵,表示每棵桃最多可以采摘的次数K。

输出格式: 一个数:PFT可以获得的最大的桃个数。

输入文件: 直接输入即可

输出文件: 直接输出即可 注意,不要在最后输出空行或空格!

样例输入: 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 0

0 0 0 0

样例输出: 10

*/

#include<climits>

#include<iostream>

#define MAXN 100

#define MAXM 100

#define MAXT 100

#define MAXA 100

using namespace std;

struct peach{

int k,i,j;

int times;

}pch[MAXM*MAXN];

int field[MAXM+1][MAXN+1];

int times[MAXM+1][MAXN+1];

int dp[MAXT+1][MAXA+1];

int main (void){

int m,n,ti,a,peaches=0;

scanf("%d %d %d %d",&m,&n,&ti,&a);

for (int i=1;i<=m;++i)

for (int j=1;j<=n;++j)

scanf("%d",&field[i][j]);

for (int i=1;i<=m;++i)

for (int j=1;j<=n;++j){

scanf("%d",&times[i][j]);

if (times[i][j]!=0&&field[i][j]!=0){

pch[peaches].i=i;

pch[peaches].j=j;

pch[peaches].k=field[i][j];

pch[peaches].times=times[i][j];

++peaches;

}

}

a--;

memset(dp,0,sizeof(dp));

for (int i=0;i<peaches;i++){

int cost=(pch[i].i+pch[i].j)*2;

for (int j=1;j<=pch[i].times;j++)

for (int t=ti;t>=cost*j;--t)

for (int pa=a;pa>=cost*j;--pa)

dp[t][pa]=max(dp[t][pa],dp[t-j*cost][pa-j*cost]+j*pch[i].k);

}

cout<<dp[ti][a];

//while(1);

return 0;

}

/*

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 0

0 0 0 0

===========

10

*/

#1 guoshi3@2008-11-09 00:38:00
回复 删除
注意这时间和体力的变化是有联系的,这种情况就可以当成一维来做。(这题中更简单,时间体力变化完全相等)

查看更多回复
提交回复