Codevs 3556 科技庄园==洛谷 P2760

时间限制: 1 s   空间限制: 128000 KB   题目等级 : 黄金 Gold
题目描述 Description

Life是codevs的用户,他是一个道德极高的用户,他积极贯彻党的十八大精神,积极走可持续发展道路,在他的不屑努力下STN终于决定让他在一片闲杂地里种桃,以亲身实践种田的乐趣,厉行节约,告诉人们节约的重要性!

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

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

PFT兴奋的说:“好啊!”

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

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

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

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

由于PFT不是机器人,所以他的体力并不是无限的,他不想摘很多的桃以至体力为0,而白白把桃给Life。同时PFT每次只能摘一棵桃树,每棵桃树都可以摘K次(对于同一棵桃每次摘的桃数相同)。每次摘完后都要返回出发点(PFT一次拿不了很多)即Life的所在地(0,0){试验田左上角的桃坐标是(1,1)}。

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

输入描述 Input Description

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

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

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

输出描述 Output Description

一个数:PFT可以获得的最大的桃个数。

样例输入 Sample Input

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

样例输出 Sample Output

10

数据范围及提示 Data Size & Hint

【样例解释】

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

【数据范围】

对于M N TI A

10<=30%<=50

10<=100%<=100

对于K

10<=100%<=100

保证结果在longint范围内

 1 #include<iostream>
 2 #include<cstdio> 
 3 #include<cstring>
 4 using namespace std;
 5 int n,m,t,a;
 6 int map[101][101],g[10010],sum,c[10000],v[10000],f[10000];
 7 int main()
 8 {
 9     scanf("%d%d%d%d",&n,&m,&t,&a);
10     t=min(t,a-1);
11     for(int i=1;i<=n;i++)
12       for(int j=1;j<=m;j++)
13         scanf("%d",&map[i][j]);
14     int k;
15     for(int i=1;i<=n;i++)
16         for(int j=1;j<=m;j++)
17         {
18             scanf("%d",&k);
19             if(map[i][j])
20             {
21                 sum++;
22                 g[sum]=(i+j)*2;v[sum]=k;
23                 c[sum]=map[i][j];
24             }
25         }
26     for(int i=1;i<=sum;i++)
27     {
28         for(int j=t;j>=0;j--)
29           for(int k=1;k<=v[i];k++)
30           {
31               if(j-k*g[i]>=0)
32                 f[j]=max(f[j],f[j-g[i]*k]+k*c[i]);
33           }
34     }
35     printf("%d",f[t]);
36     return 0;
37 }
 1 #include<iostream>
 2 #include<cstdio> 
 3 #include<cstring>
 4 using namespace std;
 5 int n,m,t,a;
 6 int map[101][101],g[10010],sum,c[10000],v[10000],f[10000];
 7 int main()
 8 {
 9     scanf("%d%d%d%d",&n,&m,&t,&a);
10     t=min(t,a-1);
11     for(int i=1;i<=n;i++)
12       for(int j=1;j<=m;j++)
13         scanf("%d",&map[i][j]);
14     int k;
15     for(int i=1;i<=n;i++)
16         for(int j=1;j<=m;j++)
17         {
18             scanf("%d",&k);
19             if(map[i][j])
20             {
21                 sum++;
22                 g[sum]=(i+j)*2;v[sum]=k;
23                 c[sum]=map[i][j];
24             }
25         }
26     for(int i=1;i<=sum;i++)
27     {
28         for(int j=t;j>=0;j--)
29           for(int k=1;k<=v[i];k++)
30           {
31               if(j-k*g[i]>=0)
32                 f[j]=max(f[j],f[j-g[i]*k]+k*c[i]);
33           }
34     }
35     printf("%d",f[t]);
36     return 0;
37 }

思路:时间 体力看上去是个二维背包,但是由于没走一个格子都是消耗一点体力一点时间,我们可以min(t,a)做成一维背包,如果这里有树,记下他的时间(记得乘以2,来回嘛!),记下他的可以采摘次数和价值,然后跑一遍背包即可

posted @ 2016-11-17 19:45  浮华的终成空  阅读(241)  评论(0编辑  收藏  举报

Contact with me