zoukankan      html  css  js  c++  java
  • codevs1166 矩阵取数游戏(区间DP)

    题目描述 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再将各行结果相加即可。

    对任意一行,设a[i]为该行第i个元素。

    d[i][j]表示该行剩余[i,j]列时已得到的最大得分。

    方程为

    d[i][j] = max{ d[i-1][j] + a[i-1]*2^(m-j+i-1),  

    d[i][j+1] + a[j+1]*2^(m-j+i-1)  }

    最后该行的最大得分是 max{ d[i][i] + a[i]*2^m } ,其中 1<=i<=n

     

    坑爹的是这题居然还要用大数,而且天梯还不支持java。。。当时调了半天终于过了那60%,然后就不想去管它了,到度娘上随便扒拉一份pascal的给交了上去。

     

    下面是我的代码。

    #include<iostream>
    #include<cassert>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<iterator>
    #include<cstdlib>
    #include<vector>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    #define rep(i,f,t) for(int i = (f),_end_=(t); i <= _end_; ++i)
    #define rep2(i,f,t) for(int i = (f),_end_=(t); i < _end_; ++i)
    #define dep(i,f,t) for(int i = (f),_end_=(t); i >= _end_; --i)
    #define dep2(i,f,t) for(int i = (f),_end_=(t); i > _end_; --i)
    #define clr(c, x) memset(c, x, sizeof(c) )
    typedef long long int64;
    const int INF = 0x5f5f5f5f;
    const double eps = 1e-8;
    
    
    //*****************************************************
    
    int64 aa[83][83];
    int64 *a;
    int64 d[83][83];
    int64 m;
    
    int64 solve()
    {
        int64 ans = 0;
        for(int64 i = 1; i <= m; ++i)
        {
            for(int64 j = m; j >= i; --j)
            {
                int64 t1 = 0, t2 = 0;
                if(i > 1)t1 = d[i-1][j] + (a[i-1]<<(m-j+i-1));
                if(j < m)t2 = d[i][j+1] + (a[j+1]<<(m-j+i-1));
                d[i][j] = max(t1,t2);
            }
            int64 tmp = d[i][i] + (a[i]<<m);
            ans = max(ans,tmp);
        }
        return ans;
    }
    
    int main()
    {
        int n;
        scanf("%d%I64d",&n,&m);
        for(int i = 1; i <= n;++i)for(int j = 1; j <= m; ++j)scanf("%I64d",&aa[i][j]);
        int64 ans = 0;
        for(int i = 1; i <= n; ++i)
        {
            a = aa[i];
            int64 tmp = solve();
            ans += tmp;
        }
        cout<<ans<<endl;
        return 0;
    }


     

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    一个简单XQuery查询的例子
    《Microsoft Sql server 2008 Internals》读书笔记第七章Special Storage(1)
    《Microsoft Sql server 2008 Internals》读书笔记第八章The Query Optimizer(4)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(4)
    SQL Server中SMO备份数据库进度条不显示?
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(5)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(3)
    《Microsoft Sql server 2008 Internal》读书笔记第八章The Query Optimizer(2)
    省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例
    FireFox意外崩溃时的手工恢复命令
  • 原文地址:https://www.cnblogs.com/DSChan/p/4862021.html
Copyright © 2011-2022 走看看