1008

来源:互联网 发布:linux 命令输入 编辑:程序博客网 时间:2024/06/06 12:58

题目编号:1008

题目大意:给你一个二维数组,从左上角走到右下角,每个格子里面有唯一的值,有正数有负数,每次只能向下移动一格或者向右一格或者向右移动到行所在列的i倍列,求最大和

解题思路:这个题目的解决也是根据背包的套路来的,当然因为里面有新颖的走法,所以需要根据不同的情况来描述问题。首先创建2个数组,一个存地图,一个存和。这里有几个细节需要说一下,为了循环需要,在1-N和1-M里面的地图来表示第一个数组,第二个和的数组行尾0,列0-n和列为0,行0-m是没有用的,避免出错,也是防止走出地图设置的,可以初始化为无限小的负数。还要把行为0列1和列为1行0的和值设置为为0,为了下面的双重循环服务。双重循环,外面是行1-你,里面是列1-m,求出和在i,j条件下到底是桌面走才最大的和,判断,赋值即可。最后输出n.m的下表的和的值。

感想:没啥想说的,就是这题好难感觉着=一变,套路都不太能行,还要自己灵活变通。

#include<iostream>#include<cstring>#include<algorithm>using namespace std;int arr[21][1001],brr[21][1001];int main(){    int t,n,m,i,j,k;    cin>>t;    while(t--)    {        cin>>n>>m;        for(i=1;i<=n;i++)            for(j=1;j<=m;j++)                cin>>arr[i][j];        for(i=0;i<=n;i++)            brr[i][0]=-99999999;        for(i=0;i<=m;i++)            brr[0][i]=-99999999;        brr[1][0]=brr[0][1]=0;        for(i=1;i<=n;i++)        {            for(j=1;j<=m;j++)            {                brr[i][j]=max(brr[i-1][j],brr[i][j-1]);                for(k=2;k<=m;k++)                {                    if(j/k==(double)j/k)                        brr[i][j]=max(brr[i][j],brr[i][j/k]);                }                brr[i][j]+=arr[i][j];            }        }        cout<<brr[n][m]<<endl;    }    return 0;}


0 0