ACM 96. [NOIP2007] 矩阵取数游戏(dp+高精度)
2014-09-08 12:01
369 查看
96. [NOIP2007] 矩阵取数游戏
★★ 输入文件:game.in输出文件:
game.out简单对比
时间限制:1 s 内存限制:128 MB
【问题描述】
帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij,均
为非负整数。游戏规则如下:
1.每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素;
2.每次取走的各个元素只能是该元素所在行的行首或行尾;
3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分=被取走的元素值*2^i,其中i表示第i次取数(从1开始编号);
4. 游戏结束总得分为m次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
【输入格式】
输入文件game.in包括n+1行:
第1行为两个用空格隔开的整数n和m。
第2-n+l行为n*m矩阵,其中每行有m个用单个空格隔开的非负整数。
【输出格式】
输出文件game.out仅包含1行,为一个整数,即输入矩阵取数后的最大得分。
【输入输出样例1】
输入:
2 3
1 2 3
3 4 2
输出:
82
【输入输出样例l解释】
第1次:第1行取行首元素,第2行取行尾元素,本次得分为1*21+2*21=6
第2次:两行均取行首元素,本次得分为2*22+3*22=20
第3次:得分为3*2^3+4*2^3=56。总得分为6+20+56=82
【输入输出样例2】
输入:
1 4
4 5 0 5
输出:
122
【输入输出样例3】
输入:
2 10
96 56 54 46 86 12 23 88 80 43
16 95 18 29 30 53 88 83 64 67
输出:
316994
【限制】
60%的数据满足:1<=n,m<=30,答案不超过10^16
100%的数据满足:l<=n,m<=80,0<=aij<=1000
#include <iostream> #include <cstring> #include <cstdio> using namespace std; #define MAX_LEN 30 #define MAX_N 81 int n,m; int mat[MAX_N]; struct BigInt { static const int BASE=1000000; static const int BIT=6; int Len; int Data[MAX_LEN]; BigInt() { Data[0]=0; Len=1; } BigInt & operator = (int num) { int len; char strnum[10]; if(num==0) { Len=1; Data[0]=0; return *this; } len=0; while(num) { strnum[len++]=num%10; num/=10; } int len8=len/BIT; if(len%BIT) len8++; for(int i=0;i<len8;i++) Data[i]=0; for(int i=len-1;i>=0;i--) { Data[i/BIT]=Data[i/BIT]*10+strnum[i]; } Len=len8; return *this; } void Print() { printf("%d",Data[Len-1]); for(int i=Len-2;i>=0;i--) { int ba=BASE/10; for(int j=0;j<=BIT;j++) { if(Data[i]>=ba) { for(int k=0;k<j;k++) { printf("0"); } if(ba>0) printf("%d",Data[i]); break; } ba/=10; } } } }; BigInt operator +(BigInt &A,BigInt &B) { BigInt C; int maxlen=max(A.Len,B.Len); int len=maxlen; int alen=A.Len,blen=B.Len; for(int i=0;i<len;i++) { C.Data[i]=0; if(i<alen) { C.Data[i]+=A.Data[i]; } if(i<blen) { C.Data[i]+=B.Data[i]; } } C.Data[len]=0; for(int i=0;i<len;i++) { C.Data[i+1]+=C.Data[i]/BigInt::BASE; C.Data[i]%=BigInt::BASE; } if(C.Data[len]) len++; C.Len=len; return C; } BigInt operator *(BigInt &A,BigInt &B) { BigInt C; int lena=A.Len,lenb=B.Len; memset(&C,0,sizeof(C)); for(int i=0;i<lenb;i++) { for(int j=0;j<lena;j++) { C.Data[i+j]+=A.Data[j]*B.Data[i]; } } for(int i=0;i<lena+lenb;i++) { C.Data[i+1]+=C.Data[i]/BigInt::BASE; C.Data[i]%=BigInt::BASE; } int i=lena+lenb-1; while(!C.Data[i]) i--; C.Len=i+1; return C; } BigInt max2(BigInt &A,BigInt &B) { if(A.Len<B.Len) return B; else if(A.Len>B.Len) return A; for(int i=A.Len-1;i>=0;i--) { if(A.Data[i]>B.Data[i]) return A; else if(A.Data[i]<B.Data[i]) return B; } return A; } BigInt dp[MAX_N][MAX_N]; int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); BigInt sum; BigInt num2; BigInt tmp1,tmp2; sum=0; num2=2; cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>mat[j]; dp[j][j]=mat[j]*2; } for(int k=2;k<=m;k++) { for(int j=1;j<=m-k+1;j++) { tmp1=mat[j];tmp2=mat[j+k-1]; tmp1=tmp1+dp[j+1][j+k-1]; tmp2=tmp2+dp[j][j+k-2]; dp[j][j+k-1]=max2(tmp1,tmp2); dp[j][j+k-1]=dp[j][j+k-1]*num2; } } sum=sum+dp[1][m]; } sum.Print(); cout<<endl; return 0; }
相关文章推荐
- 【NOIP2007提高组T3】矩阵取数游戏-动态规划+高精度
- noip2007 矩阵取数游戏 (动态规划+高精度)
- NOIP2007 矩阵取数游戏 [dp] [高精度]
- NOIP2007 矩阵取数 DP+高精度
- Codevs_1166_[NOIP2007]_矩阵取数游戏_(动态规划+高精度)
- dp+高精度(洛谷1005 矩阵取数游戏NOIP 2007 提高第三题)
- [NOIP 2007] 矩阵取数游戏:DP,高精度
- NOIP2007 矩阵取数游戏
- [NOIP2007] 矩阵取数游戏 【记忆化搜索+高精】
- NOIP2007提高组——矩阵取数游戏(game)
- NOIP2007【矩阵取数游戏】
- NOIP2007 提高组 复赛 game 矩阵取数游戏
- noip 2007矩阵取数游戏luogu1005
- [NOIP2007] 提高组 洛谷P1005 矩阵取数游戏
- 矩阵取数游戏 2007年NOIP全国联赛提高组(dp+高精)
- 洛谷P1005&NOIP2007 矩阵取数游戏
- 【NOIP2007】矩阵取数游戏
- [NOIP2007] 矩阵取数游戏
- [NOIp2007提高组]矩阵取数游戏
- 【NOIP2007】洛谷1005 矩阵取数游戏