【问题描述】
小新正在玩一个电脑游戏:
有一条环形道路,路上有n个机器人工厂,按顺时针方向编号1~n,相邻工厂之间的n段路也编号1~n,规定:i号路段连接i和i+1号工厂,n号路段连接n和1号工厂。
游戏时,每分钟每段路上都会出现一些金币,不同时间在同一路段出现的金币数可能不同。小新需要操控机器人收集金币。机器人必须在工厂购买,购买后机器人顺路行走,每分钟走一段路,并收集路上的所有金币。如:在i号厂买的机器人,就从i号厂开始,用1分钟经过i号路段,到达i+1号厂,并收集i号路段的所有金币。
环形道路上同时只能有1个机器人,每个机器人最多连续走p分钟,中断行走或走完p分钟它会自动消失。
以下是补充说明:
1、游戏从小新第一次购买机器人开始计时。
2、购买机器人瞬间完成。
3、购买机器人的费用在同一工厂相同,但在不同工厂不一定相同。
4、购买机器人的金币,游戏结束时从收集的金币中扣除。因此,最终的金币数可能为负。
现在已知:每分钟每段路出现的金币数,以及在每个厂购买机器人的费用。
请你计算:经过m分钟后,扣除购买机器人的花费,小新最多能收到多少金币。
【输入】第一行:n,m,p
下接n行,每行:m个整数,一个空格相隔
第i行第j个数:表示第j分钟i号路段的金币数(1≤金币数≤100)。
最后一行:n个整数,一个空格相隔
第i个数:表示在i号厂购买机器人的金币数(1≤金币数≤100)。
【输出】1个整数,表示最多能得到的金币数。
【样例】
game.in | game.out |
2 3 2 1 2 3 2 3 4 1 2 | 5 |
【数据范围】
对于40%的数据,2≤n≤40,1≤m≤40
对于90%的数据,2≤n≤200,1≤m≤200
对于100%的数据,2≤n≤1000,1≤m≤1000,1≤p≤m
附AC码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
int f[1010][1010];
int t[1010][1010];
int b[1010][1010];
int cost[1010];
int q[1010]={0};
int main(){
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
int i,j,k,m,n,p,qmax=0,nmax=0;
scanf("%d%d%d",&n,&m,&p);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&b[j][i]);
for(i=1;i<=n;i++)
scanf("%d",&cost[i]);
for(i=1;i<=n;i++)
q[i]=(i+n-2)%n+1;
for(i=1;i<=n;i++)
t[0][i]=p;
for(i=1;i<=m;i++){
nmax=-214748368;
for(j=1;j<=n;j++){
if(t[i-1][q[j]]<p && f[i-1][q[j]]>qmax-cost[q[j]]){
t[i][j]=t[i-1][j]+1;
f[i][j]=f[i-1][q[j]]+b[i][q[j]];
}else{
t[i][j]=1;
f[i][j]=qmax-cost[q[j]]+b[i][q[j]];
}
if(f[i][j]>nmax)nmax=f[i][j];
}
qmax=nmax;
}
printf("%d\n",nmax);
return 0;
}