其他分享
首页 > 其他分享> > 题解:科技庄园

题解:科技庄园

作者:互联网

目录

题目

题目背景

Life种了一块田,里面种了有一些桃树。
Life对PFT说:“我给你一定的时间去摘桃,你必须在规定的时间之内回到我面前,否则你摘的桃都要归我吃!”
PFT思考了一会,最终答应了
由于PFT的数学不好!它并不知道怎样才能在规定的时间获得最大的价值,
由于PFT不是机器人,所以他的体力并不是无限的,他不想摘很多的桃以至体力为0,而白白把桃给Life。同时PFT每次只能摘一棵桃树,,每棵桃树都可以摘K次(对于同一棵桃每次摘的桃数相同)。每次摘完后都要返回出发点(PFT一次拿不了很多)即Life的所在地(0,0){试验田左上角的桃坐标是(1,1)}。
PFT每秒只能移动一个单位,每移动一个单位耗费体力1(摘取不花费时间和体力,但只限上下左右移动)。

输入格式

第一行:四个数为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

解析

万物皆可01背包
对于这道题,我们考虑将其转化成01背包。为什么转成01背包呢?(因为我只会01背包的板子)
怎么转成01背包呢?对于每一个桃树,每次采摘的桃子数量即为价值,一来一回,所时间和体力即为花费,即为横纵坐标之和的二倍,而对于每一棵桃树的n次采摘机会,我们直接将其视为n棵花费和价值都相同的桃树,这样把所有的桃树都处理一遍,然后当成01背包来做就可以了

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int N,M,TI,A;
int tree1[1001][1001];
int tree2[1001][1001];
struct tree{
    int dis,pea,tim;
}a[10001];
int dp[1001][1001];
signed main() {
    scanf("%lld %lld %lld %lld" ,&N,&M,&TI,&A);
    for(int i = 1; i <= N; i++) {
	    for(int j = 1; j <= M; j++) {
		    scanf("%lld" ,&tree2[i][j]);
	    }
    }
    for(int i = 1; i <= N; i++) {
	    for(int j = 1; j <= M; j++) {
		    scanf("%lld" ,&tree1[i][j]);
	    }
    }
    int tot = 1;
    for(int i = 1;i <= N; i++) {
	    for(int j = 1;j <= M; j++) {
		    if(tree1[i][j] != 0) {
			    for(int k = 1;k <= tree1[i][j]; k++){
				    a[tot].dis = (i + j) * 2;
				    a[tot].pea = tree2[i][j];
				    a[tot].tim = (i + j) * 2;
				    tot++;
			    }
		    }   
	    }
    }
    tot--;
    for(int i = 1;i <= tot; i++) {
	    for(int j = TI;j >= a[i].tim; j--) {
		    for(int k = A;k > a[i].dis; k--) {
			    dp[j][k] = max(dp[j][k],dp[j - a[i].tim][k - a[i].dis] + a[i].pea);
		    }
	    }
    }
    printf("%lld" ,dp[TI][A]);
    return 0;
}

标签:庄园,int,题解,科技,01,PFT,桃树,1001,lld
来源: https://www.cnblogs.com/Crazyman-W/p/14864438.html