动态规划——猴子

Description

在hphp还没有电脑的时候,手机是她唯一的娱乐工具,最喜欢玩的游戏就是猴子,猴子的行动范围是在n(n<=100)根水平排列的柱子的底端上,并且以坐虫子为快乐。每坐到一个虫子他就快乐一点。可是他的快乐是有极限的,因为他只能水平的在相邻的柱子间移动,并且移动一次时间是1s,如果在时间t(0<=t<=10000)猴子刚好在柱子m(1<=m<=n)上并且此时m上恰好会出现一只虫子,那么猴子就可以坐到它了。现在猴子最初(0s)在1号柱子上,在t时间m柱子上是否能有虫子以一个矩阵给出。猴子想要最快乐,你是否能够帮助它呢~

Input

多组测试数据,每组测试数据首先给出整数n,t (0<n<=100,0<=t<=10000)占一行。n表示总共有多少柱子,t表示游戏结束的时间,t时间猴子就不可以再坐虫子咯。接下来有n行,每行有t个整数(0或1)T0,T2....Tt-1。第i行第j个数字表示第i个柱子在j时间是否有虫子出现。

Output

对于每组测试数据输出一个整数,表示猴子快乐的最大点数。

Sample Input

3 4
0 1 0 1
1 0 0 1
1 1 1 1
3 4
1 0 1 0
1 1 1 0
1 1 1 1
1 5
1 0 1 0 1

Sample Output

2
4
3

思路引导

(1)首先一定和所在柱子有关系

(2)和时间也有关系

(3)显然在条件确定的情况下是满足最优子结构的,即可以用dp解决

解题报告

 用max[i][j]表示在第i时间在第j个柱子上时能得到的最大的幸福值;grid[i][j]表示第i时间第j柱子是否有虫子。那么mx[i][j]=Max(mx[i-1][j-1],m[i-1[j],mx[i-1][j+1])+grid[j][i].边界问题要特别注意。

源代码:

#include<stdio.h>
#define MAX (1<<29)
#define N 110
#define T 10100
#define Max(a,b,c) (((a)>(b)?(a):(b))>(c)?((a)>(b)?(a):(b)):(c))//找出三个数中最大的数
int mx[T][N], //mx[i][j]表示在第i时间在第j个柱子上时能够得到的最大的幸福值
 grid[N][T]; //grid[i][j]表示第i时间在第j个柱子上是否有虫子
int n,   //表示共有多少个柱子
 limt;  //表示游戏结束的时间

int main()
{
 while(scanf("%d %d",&n,&limt)!=EOF)
 {
  for(int i=1;i<=n;i++)
  {
   for(int j=0;j<limt;j++)
   {
    scanf("%d",&grid[i][j]);
   }
  }
  for(int i=1;i<=n;i++)
  {
   for(int j=0;j<limt;j++)
    mx[j][i]=-MAX; //赋初值
  }

  mx[0][1] = grid[1][0]; //若第一个柱子在第一秒有虫子,则至少可琢一个虫子
  for(int i=1;i<limt;i++)
  {
   for(int j=1;j<=n&&j<=i+1;j++)
   {
    int a=-MAX,b=-MAX,c=-MAX;//a、b、c分别表示相邻三根柱子上获得最大幸福值
    if(j>1)  //考虑左边界问题
     a=mx[i-1][j-1];
    b=mx[i-1][j];
    if(j<n)  //考虑右边界问题
     c=mx[i-1][j+1];
    mx[i][j]=Max(a,b,c)+grid[j][i];
   }
  }
  int mxmx=0;
  for(int i=1;i<=n;i++)
   if(mx[limt-1][i]>mxmx)
    mxmx=mx[limt-1][i];
  printf("%d\n",mxmx);
 }
 return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值