码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵取数游戏

时间:2019-06-09 09:20:11      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:题意   getchar   oid   href   names   i++   getc   etc   编号   

洛咕

帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的\(M*N\)的矩阵,矩阵中的每个元素\(a_{i,j}\)均为非负整数.游戏规则如下:

1,每次取数时须从每行各取走一个元素,共n个.经过m次后取完矩阵内所有元素;

2,每次取走的各个元素只能是该元素所在行的行首或行尾;

3,每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值\(*2^i\),其中i表示第i次取数(从1开始编号);

4,游戏结束总得分为m次取数得分之和.

给定一个矩阵,求最大总得分.

分析:做本题前推荐做一下数据弱化版奶牛零食.根据题意不难发现,每一行的游戏都是独立的,所以实际上本题就是跑n次奶牛零食:设\(f[i][j][l][r]\)表示第i行第j次取数,区间\([l,r]\)能够获得的最大得分.

\(f[i][j][l][r]=max(f[i][j][l][r],max(f[i][j][l-1][r]+now*a[i][l-1],f[i][j][l][r+1]+now*a[i][r+1]))\)

\(now\)可以预处理,也可以每次循环乘个2得到.

其实第一维和第二维都可以不要,但是只要滚掉一维就可以过了.

本题要写高精,\(__int128\)水过就行.

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
const int N=85;
__int128 ans,a[N][N],f[N][N][N];
inline void print(__int128 x){    
   if(x<0){putchar('-');x=-x;}
   if(x>9)print(x/10);
   putchar(x%10+'0');
}
int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=read();
    for(int i=1;i<=n;i++){
        __int128 now=1;
        for(int j=1;j<=m-1;j++){
            now*=2;
            for(int l=1;l<=j+1;l++){
                int r=l+m-j-1;
                f[i][l][r]=max(f[i][l][r],max(f[i][l-1][r]+now*a[i][l-1],f[i][l][r+1]+now*a[i][r+1]));
            }
        }
        __int128 maxn=0;
        for(int j=1;j<=m;++j)maxn=max(maxn,f[i][j][j]+now*2*a[i][j]);
        ans+=maxn;
    }
    print(ans);cout<<endl;
    return 0;
}

矩阵取数游戏

标签:题意   getchar   oid   href   names   i++   getc   etc   编号   

原文地址:https://www.cnblogs.com/PPXppx/p/10992507.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!