zoukankan      html  css  js  c++  java
  • 矩阵取数游戏【NOIP】

    题目描述 Description

    【问题描述】
    帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均
    为非负整数。游戏规则如下:
    1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素;
    2. 每次取走的各个元素只能是该元素所在行的行首或行尾;
    3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素值*2i,
    其中i 表示第i 次取数(从1 开始编号);
    4. 游戏结束总得分为m次取数得分之和。
    帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。

    输入描述 Input Description

    第1行为两个用空格隔开的整数n和m。
    第2~n+1 行为n*m矩阵,其中每行有m个用单个空格隔开的非负整数。

    输出描述 Output Description

    输出 仅包含1 行,为一个整数,即输入矩阵取数后的最大得分。

    样例输入 Sample Input

    2 3
    1 2 3
    3 4 2

    样例输出 Sample Output

    82

    数据范围及提示 Data Size & Hint

    样例解释

    第 1 次:第1 行取行首元素,第2 行取行尾元素,本次得分为1*21+2*21=6
    第2 次:两行均取行首元素,本次得分为2*22+3*22=20
    第3 次:得分为3*23+4*23=56。总得分为6+20+56=82

     

    【限制】
    60%的数据满足:1<=n, m<=30, 答案不超过1016
    100%的数据满足:1<=n, m<=80, 0<=aij<=1000


    思路:

    似乎是个区间DP,虽然给的是个矩阵,但我们一行一行取,不影响结果

    很显然,以区间长度作为DP对象,把一整长序列一小段一小段拆解,在逐渐合并结果,以局部最优推导全局最优。有点类似于归并排序的分治思想

    我们每选取一个数,相当于整个区间自带了一个 x2 buff ,就不需要管他是第几次取的

    但这道题麻烦不在于DP方程,而在于高精度

    60:long long code

    #include<stdio.h> 
    #include<string.h>
    #include<algorithm> 
    #define ll long long 
    using namespace std;
    ll ans,game[110][110],f[110][110];;
    int n,m;
    
    inline int read() {
        int s=0,f=1;
        char ch=getchar();
        while(ch<'0' || ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } 
        while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar();
        return s*f;
    } 
    
    void Sol(ll a[]) 
    {
        memset(f,0,sizeof(f));
        for(int len=0;len<m;++len) {
            for(int i=1;i+len<=m;++i) {
                f[i][i+len]=max(2*f[i+1][i+len]+2*a[i],2*f[i][i+len-1]+2*a[i+len]); 
            }
        }
        ans+=f[1][m];
    }
    
    int main() 
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) {
            for(int j=1;j<=m;++j) {
                game[i][j]=read();
            }
        }
        for(int i=1;i<=n;++i) Sol(game[i]);
        printf("%lld",ans);
        return 0;
    }
    /*
    2 3
    1 2 3
    3 4 2
    */

    AC:int128 偷懒写法 >:<(NOIP不让用哦)

    #include<stdio.h> 
    #include<string.h>
    #include<algorithm> 
    #define bll __int128
    using namespace std;
    bll ans,game[110][110],f[110][110];
    int n,m;
    
    inline int read() {
        int s=0,f=1;
        char ch=getchar();
        while(ch<'0' || ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } 
        while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar();
        return s*f;
    } 
    
    void Sol(bll a[]) 
    {
        memset(f,0,sizeof(f));
        for(int len=0;len<m;++len) {
            for(int i=1;i+len<=m;++i) {
                f[i][i+len]=max(2*f[i+1][i+len]+2*a[i],2*f[i][i+len-1]+2*a[i+len]); 
            }
        }
        ans+=f[1][m];
    }
    
    void print(bll x) {
        if(!x) return ;
        if(x) print(x/10);
        putchar(x%10+'0');
    }
    
    int main() 
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) {
            for(int j=1;j<=m;++j) {
                game[i][j]=read();
            }
        }
        for(int i=1;i<=n;++i) Sol(game[i]);
        if(!ans) printf("0");
        else print(ans); 
        return 0;
    }
    /*
    2 3
    1 2 3
    3 4 2
    */
  • 相关阅读:
    hibernate_0100_HelloWorld
    MYSQL子查询的五种形式
    JSF是什么?它与Struts是什么关系?
    nop指令的作用
    htmlparser实现从网页上抓取数据(收集)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the
    FCKeditor 在JSP上的完全安装
    Java遍历文件夹的2种方法
    充电电池和充电时间说明
    吃知了有什么好处
  • 原文地址:https://www.cnblogs.com/qseer/p/9803548.html
Copyright © 2011-2022 走看看