记录编号 33757 评测结果 AAAAAAAAAA
题目名称 [NOIP 2007]矩阵取数游戏 最终得分 100
用户昵称 GravatarTruth.Cirno 是否通过 通过
代码语言 C++ 运行时间 0.436 s
提交时间 2011-11-11 19:34:49 内存使用 0.79 MiB
显示代码纯文本
#include <cstdio>
#include <memory.h>
using namespace std;

struct bint
{
	int len,num[20];
};

int m,a[81];
bint num2,total={0},f[81][81];

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

bint bchange(int a)
{
	bint temp={0};
	while (a)
	{
		temp.num[temp.len++]=a%10000;
		a/=10000;
	}
	return(temp);
}

void bprint(bint a)
{
	if (a.len==0)
	{
		printf("0");
		return;
	}
	int i;
	printf("%d",a.num[a.len-1]);
	for (i=a.len-2;i>=0;i--)
		printf("%04d",a.num[i]);
}

bint bplu(bint a,bint b)
{
	int i;
	if (a.len<b.len)
		a.len=b.len;
	for (i=0;i<a.len;i++)
		a.num[i]+=b.num[i];
	for (i=0;i<a.len;i++)
		if (a.num[i]>10000)
		{
			a.num[i+1]++/*+=a.num[i]/10000*/;
			a.num[i]-=/*%=*/10000;
		}
	if (a.num[a.len]!=0)
		a.len++;
	return(a);
}

bint btim(bint a,bint b)
{
	bint temp={0};
	int i,j;
	temp.len=a.len+b.len-1;
	for (i=0;i<a.len;i++)
		for (j=0;j<b.len;j++)
			temp.num[i+j]+=a.num[i]*b.num[j];
	for (i=0;i<temp.len;i++)
		if (temp.num[i]>10000)
		{
			temp.num[i+1]+=temp.num[i]/10000;
			temp.num[i]%=10000;
		}
	if (temp.num[temp.len]!=0)
		temp.len++;
	return(temp);
}

void dp(void)
{
	int i,j;
	bint temp;
	memset(f,0,sizeof(f));
	for (j=1;j<=m;j++)
		for (i=1;i<=m-j+1;i++)
		{
			f[i][j]=btim(bplu(f[i][j-1],bchange(a[i+j-1])),num2);
			temp=btim(bplu(f[i+1][j-1],bchange(a[i])),num2);
			if (bcmp(f[i][j],temp)==1)
				f[i][j]=temp;
		}
	total=bplu(total,f[1][m]);
}

int main(void)
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	num2=bchange(2);
	int i,j,n;
	scanf("%d %d\n",&n,&m);
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=m;j++)
			scanf("%d",&a[j]);
		dp();
	}
	bprint(total);
	printf("\n");
	fclose(stdin);
	fclose(stdout);
	return(0);
}