Result | TIME Limit | MEMORY Limit | Run Times | AC Times | JUDGE |
---|---|---|---|---|---|
![]() | 3s | 8192K | 104 | 19 | Standard |
10*10的格子(1,1)-(10,10)。一个人开始(0秒)站在(1,1)点。每秒他最多可以移动v个格子(但是只能是上下左右,不可以斜着移动)。每一秒钟,天空中会有礼物落下来。当这个人这一秒移动结束后停在某一个格子中,他就可以得到这一秒落到这个格子里的所有礼物。时间一共有t秒。由于礼物的价值是不同的。他想让收集到的礼物价值和最大。请你编程输出他所得到礼物价值和的最大值。
Input
多组输入,每组如下:
第一行v,t,m。表示每秒最多移动v个格子,时间共t秒(1 <=t <= 100),一共会落下m件礼物。
以下m行每行为time,x,y,c。表示在time秒(1<=time<=t),(x,y)格子会有价值为c(正整数)的礼物落下。 v=t=m=0表示输入结束,你不必处理此行。
Output
每组一行,一个整数表示得到礼物的最大价值。
Sample Input
9 2 2 1 1 1 10 2 10 10 100 0 0 0
Sample Output
100
This problem is used for contest: 160
原来错误的代码
#include<stdio.h>
#include<string.h>
int val[101][11][11],f[101][11][11];
int ab(int a)
{
if(a<0) return -a;
return a;
}
int main()
{
int v,t,m,i,x,y,time,c,xx,yy,j;
long long max;
while(scanf("%d%d%d",&v,&t,&m)!=EOF)
{
if(v==0&&t==0&&m==0) break;
memset(val,0,sizeof(val));
memset(f,0,sizeof(f));
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&time,&x,&y,&c);
val[time][x][y]+=c;
}
for(i=1;i<=t;i++)
for(x=1;x<=10;x++) //要跳到的格子
for(y=1;y<=10;y++)
{
if(i!=1)
{
for(xx=1;xx<=10;xx++) //枚举跳之前的格子
for(yy=1;yy<=10;yy++)
if((ab(xx-x)+ab(yy-y))<=v && f[i][x][y]<f[i-1][xx][yy]+val[i][x][y] )
f[i][x][y]=f[i-1][xx][yy]+val[i][x][y];
}
else
{
if((ab(x-1)+ab(y-1))<=v)
{
f[i][x][y]=val[i][x][y];
}
}
}
max=0;
for(i=1;i<=t;i++)
for(x=1;x<=10;x++)
for(y=1;y<=10;y++)
if(max<f[i][x][y]) max=f[i][x][y];
printf("%lld/n",max);
}
return 0;
}
没有做好从1,1点出发这个重要的初始化,对图的记忆化不好
这是改过的代码
#include<stdio.h>
#include<string.h>
#include <limits.h>
int val[101][11][11],f[101][11][11];
int ab(int a)
{
if(a<0) return -a;
return a;
}
int main()
{
int v,t,m,i,x,y,time,c,xx,yy,j;
long long max;
while(scanf("%d%d%d",&v,&t,&m)!=EOF)
{
if(v==0&&t==0&&m==0) break;
memset(val,0,sizeof(val));
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&time,&x,&y,&c);
val[time][x][y]+=c;
}
for(i = 1; i <= 10; ++i) for(j = 1; j <= 10; ++j) f[0][i][j] = INT_MIN;
f[0][1][1] = 0;
for(i=1;i<=t;i++)
for(x=1;x<=10;x++) //要跳到的格子
for(y=1;y<=10;y++)
{
int max = INT_MIN;
for(xx=1;xx<=10;xx++) //枚举跳之前的格子
for(yy=1;yy<=10;yy++)
if((ab(xx-x)+ab(yy-y))<=v)
max = max < f[i - 1][xx][yy]+val[i][x][y]? f[i - 1][xx][yy]+val[i][x][y] : max;
f[i][x][y] = max;
}
max=0;
for(i=1;i<=t;i++)
for(x=1;x<=10;x++)
for(y=1;y<=10;y++)
if(max<f[i][x][y]) max=f[i][x][y];
printf("%lld/n",max);
}
return 0;
}
第二个代码
#include<stdio.h>
#include<string.h>
#include <limits.h>
int val[101][11][11],f[101][11][11];
int ab(int a)
{
if(a<0) return -a;
return a;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int v,t,m,i,x,y,time,c,xx,yy,j,k;
long long max;
while(scanf("%d%d%d",&v,&t,&m)!=EOF)
{
if(v==0&&t==0&&m==0) break;
memset(val,0,sizeof(val));
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&time,&x,&y,&c);
val[time][x][y]+=c;
}
for(k=0;k<=t;k++) for(i = 1; i <= 10; ++i) for(j = 1; j <= 10; ++j) f[k][i][j] = INT_MIN;
f[0][1][1] = 0;
for(i=1;i<=t;i++)
for(x=1;x<=10;x++) //要跳到的格子
for(y=1;y<=10;y++)
{
if(i!=1)
{
for(xx=1;xx<=10;xx++) //枚举跳之前的格子
for(yy=1;yy<=10;yy++)
if((ab(xx-x)+ab(yy-y))<=v && f[i][x][y]<f[i-1][xx][yy]+val[i][x][y] )
f[i][x][y]=f[i-1][xx][yy]+val[i][x][y];
}
else
{
if((ab(x-1)+ab(y-1))<=v)
{
f[i][x][y]=val[i][x][y];
}
}
}
max=0;
for(i=1;i<=t;i++)
for(x=1;x<=10;x++)
for(y=1;y<=10;y++)
if(max<f[i][x][y]) max=f[i][x][y];
printf("%lld/n",max);
}
return 0;
}