JOJ 2650: 礼物


ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
3s8192K10419Standard

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值