矩阵取数游戏 [Codevs 1166]

来源:互联网 发布:有人买过淘宝店吗 编辑:程序博客网 时间:2024/06/06 03:41

题目地址请点击——


矩阵取数游戏


Description


Input

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


Output

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


Sample Input

2 3
1 2 3
3 4 2


Sample Output

82


Data Size & Hint

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


Solution

首先,我们可以分行处理。
对于每一行,设 fi,j 表示 ij 的最大得分。
则可以分成两种情况:
一:选择最左端的数字。
二:选择最右端的数字。
fi,j=Max(fi,j1+numl,j×2m(ji),fi+1,j+numl,i×2m(ji))
其中,l 表示当前的行号, numi,j 表示原矩阵中第 i 行第 j 列的数字。


Code

#include <iostream>#include <cstdio>#include <cstring>#define Max(x,y) ((x)>(y)?(x):(y))#define LL long long#define MOD 10000000using namespace std;char ss[50];struct bign{    LL s[50],len;    bign(){        memset(s,0,sizeof s);        s[1]=0;        len=1;    }    bign(const int num){        *this=num;    }    bign operator = (const int &num){        sprintf(ss,"%d",num);        return *this=ss;    }    bign operator = (const char*str){        s[1]=0;        len=(strlen(str)-1)/7+1;        LL yu=strlen(str)%7-1,wei=len;        for(LL i=0;i<=yu;i++)s[wei]=s[wei]*10+str[i]-'0';        for(LL i=yu+1;i<len;i+=7){            --wei;            for(LL j=0;j<7;j++)                s[wei]=s[wei]*10+str[i+j]-'0';        }        return *this;    }    bign operator * (const bign &num){        bign c;        c.len=num.len+len;        for(int i=1;i<=len;i++)            for(int j=1;j<=num.len;j++){                c.s[i+j]+=(num.s[j]*s[i]+c.s[i+j-1])/MOD;                c.s[i+j-1]=(num.s[j]*s[i]+c.s[i+j-1])%MOD;            }        while(!c.s[c.len]&&c.len>1)c.len--;        return c;    }    bign operator + (const bign&num){        bign c;        c.s[1]=0;        c.len=Max(num.len,len);        for(LL i=1;i<=c.len;i++){            c.s[i+1]=(c.s[i]+s[i]+num.s[i])/MOD;            c.s[i]=(c.s[i]+s[i]+num.s[i])%MOD;        }        if(c.s[c.len+1])c.len++;        return c;    }    bool operator > (const bign&num)const{        if(len!=num.len)return len>num.len;        for(LL i=len;i>=1;i--)            if(s[i]!=num.s[i])                return s[i]>num.s[i];        return false;    }    void out(){        for(LL i=len;i>=1;i--){            if(i==len)printf("%lld",s[i]);            else printf("%07lld",s[i]);        }    }};int n,m;bign ans;int num[100][100];bign f[100][100];bign tmpss=1,tmpss2=2;bign power(int y){    if(y==0)return tmpss;    if(y==1)return tmpss2;    bign tmp=power(y/2);    tmp=tmp*tmp;    if(y&1)tmp=tmp*tmpss2;    return tmp;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            scanf("%d",&num[i][j]);    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++)            f[j][j]=power(m)*num[i][j];        for(int j=m;j>=1;j--)            for(int k=j+1;k<=m;k++)                f[j][k]=Max(f[j+1][k]+power(m-(k-j))*num[i][j],f[j][k-1]+power((m-(k-j)))*num[i][k]);        ans=ans+f[1][m];    }    ans.out();    return 0;}
0 0
原创粉丝点击