记录编号 108195 评测结果 AAAAAAAAAA
题目名称 [NOIP 2007]矩阵取数游戏 最终得分 100
用户昵称 GravatarJSX 是否通过 通过
代码语言 C++ 运行时间 0.192 s
提交时间 2014-07-02 17:01:23 内存使用 1.11 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 10000
using namespace std;

struct Bign{
	int len;
	int num[20];
};

int N;
int a[101];

Bign Bign_2={0};
	
Bign Bign_Sum={0},f[101][101];
Bign My_Change(int a);
Bign My_Add(Bign a,Bign b);//高精加 
Bign My_Mul(Bign a,Bign b);//高精乘 
bool My_Comp(Bign a,Bign b);//比较 
void My_Print(Bign a);

void Huali_Work()
{
	memset(f,0,sizeof(f));
	
	Bign temp={0};
	for(int j=1;j<=N;++j)
	{
		for(int i=1;i<=N-j+1;++i)
		{
			Bign a1=My_Change(a[i+j-1]);
			Bign a2=My_Change(a[i]);
			
			f[i][j]=My_Mul(My_Add(f[i][j-1],a1),Bign_2);
			temp=My_Mul(My_Add(f[i+1][j-1],a2),Bign_2);
			
			if(My_Comp(f[i][j],temp)==1)
			{
				f[i][j]=temp;
			}
		}
	}
	
	Bign_Sum=My_Add(Bign_Sum,f[1][N]);
} 

int main()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	Bign_2.num[0]=2;
	Bign_2.len=1;
	
	int M;
	scanf("%d%d",&M,&N);
	
	for(int j=1;j<=M;++j)
	{
		for(int i=1;i<=N;++i)
		{
			scanf("%d",&a[i]);
		}
		Huali_Work();
	}
	
	printf("%d",Bign_Sum.num[Bign_Sum.len-1]);
	
	for(int i=Bign_Sum.len-2;i>=0;--i)
	{
		printf("%04d",Bign_Sum.num[i]); 
	} 
	
	return 0;
}

Bign My_Change(int a)
{
	Bign temp={0};
	
	while(a)
	{
		temp.num[temp.len++]=a%MAXN;
		a/=MAXN;
	}
	return temp;
}
Bign My_Mul(Bign a,Bign b)//高精乘 
{
	Bign temp={0};
	temp.len=a.len+b.len-1;//注意要减一 
	for(int i=0;i<a.len;++i)
	{
		for(int j=0;j<b.len;++j)
		{
			temp.num[i+j]+=a.num[i]*b.num[j];
		}
	}
	for(int i=0;i<temp.len;++i)
	{
		if(temp.num[i]>MAXN)
    	{
    		temp.num[i+1]+=temp.num[i]/MAXN;
    		temp.num[i]%=MAXN;
    	}
	}
	if(temp.num[temp.len]!=0) temp.len++;
	
	return temp;
}

Bign My_Add(Bign a,Bign b)//高精加 
{
	if(a.len<b.len) a.len=b.len;
    
    for(int i=0;i<a.len;++i) a.num[i]+=b.num[i];
    
    for(int i=0;i<a.len;++i)
    {
    	if(a.num[i]>MAXN)
    	{
    		a.num[i+1]++;
    		a.num[i]-=MAXN;
    	}
    }
    
    if(a.num[a.len]!=0) a.len++;
    
    return a;
}

bool My_Comp(Bign a,Bign b)
{
	if(a.len<b.len) return 1;
	if(a.len>b.len) return 0;
	
	for(int i=a.len-1;i>=0;--i)
	{
		if(a.num[i]>b.num[i]) return 0;
		if(a.num[i]<b.num[i]) return 1;
	}
	
	return 0;
}