Date:2022.03.17
题目背景
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可以获得的最大的桃个数。
输入输出样例
输入 #1复制
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
输出 #1复制
10
说明/提示
样例说明:
可以摘到1次(1,1)和1次(2,3),体力和时间不满足再摘桃了。
范围:
对于M,N,TI,A 10<=30%<=50 10<=100%<=100
对于K 10<=100%<=100
保证结果在long int范围内
思路:f[i][j]:f[i][j]:f[i][j]:串1选前iii个字符,串2选前jjj个字符,对齐它的最小花费。在此状态下,有意义的s1[i]、s2[j]s1[i]、s2[j]s1[i]、s2[j]只能是三种情况:
①字符和空格:f[i][j−1]+k;f[i][j-1]+k;f[i][j−1]+k;
②空格和字符:f[i−1][j]+k;f[i-1][j]+k;f[i−1][j]+k;
③字符和字符:f[i−1][j−1]+dis(a[i],b[j]);f[i-1][j-1]+dis(a[i],b[j]);f[i−1][j−1]+dis(a[i],b[j]);
在a[i]a[i]a[i]、b[j]b[j]b[j]处俩都加空格显然无意义。
此外,初始状态有两类不为0,且分别表示从另一个串前面添加若干空格。
①f[i][0]=i∗k;【i∈[1,n]】f[i][0]=i*k;【i\in[1,n]】f[i][0]=i∗k;【i∈[1,n]】
②f[0][j]=j∗k;【j∈[1,n]】f[0][j]=j*k;【j\in[1,n]】f[0][j]=j∗k;【j∈[1,n]】
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2020,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
string a,b;
LL n,m,k,f[N][N];
LL dis(char c1,char c2) {return abs(c1-c2);}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
string aa,bb;cin>>aa>>bb>>k;n=aa.length();m=bb.length();
a=" ";a+=aa;b=" ";b+=bb;
for(int i=1;i<=n;i++) f[i][0]=i*k;
for(int j=1;j<=m;j++) f[0][j]=j*k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
f[i][j]=min(min(f[i-1][j],f[i][j-1])+k,f[i-1][j-1]+dis(a[i],b[j]));
cout<<f[n][m];
return 0;
}
这篇博客探讨了一个关于在有限时间内最大化采摘桃子的问题。PFT需要在指定的田地中找到一条路径,使得在体力和时间限制下,能够采摘到最多的桃子。输入包括田地的尺寸、时间限制和PFT的体力,输出是最大可能采摘的桃子数量。该问题可以通过动态规划来解决,计算每个位置的最大收益。代码示例展示了如何实现这个算法。
1249

被折叠的 条评论
为什么被折叠?



