codevs 1166 矩阵取数游戏 (2007 noip)

首先可以判断这是一个dp,然后这个矩阵中各个行之间是没有联系的,所以可以一行一行地求出最优解然后通过循环加起来

不是一个特别难的dp 但是在数目问题上比较大 反正一看到平方啊这种东西应该差不多会溢出的……所以写一个高精度的结构体 就ok了!!


代码在这:

#include <bits/stdc++.h>
#include <iostream>

using namespace std;


const int maxn=85;
int n,m;
int temp[maxn][maxn];

const int power=4;
const int base=10000;
const int maxl=35;

struct num{
	int a[maxl];

	num(){
		memset(a,0,sizeof(a));
	}

	num operator + (const num &b){
		num c;
		c.a[0]=max(a[0],b.a[0]);
		for(int i=1;i<=c.a[0];++i){
			c.a[i]+=a[i]+b.a[i];
			c.a[i+1]+=c.a[i]/base;
			c.a[i]=c.a[i]%base;
		}
		if(c.a[c.a[0]+1]) ++c.a[0];
		return c;
	}

	num operator + (const int &b){
		a[1]+=b;
		int i=1;
		while(a[i]>=base){
			a[i+1]+=a[i]/base;
			a[i]%=base;
			i++;
		}
		while(a[a[0]+1]) ++a[0];
		return *this;
	}

	num operator = (int b){
		a[0]=0;
		while(b){
			a[0]++;
			a[a[0]]=b%base;
			b/=base;
		}
		return *this;
	}

	bool operator < (const num &b)const{
		if(a[0]<b.a[0]) return true;
		if(a[0]>b.a[0]) return false;
		for(int i=a[0];i>0;--i)
			if(a[i]!=b.a[i]) return a[i]<b.a[i];
		return false;
	}

	void print(){
		printf("%d",a[a[0]]);
		for(int i=a[0]-1;i>0;--i)
			printf("%0*d",power,a[i]);
		printf("\n");
	}
}ans,s[maxn][maxn];

int main()
{

	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			scanf("%d",&temp[i][j]);

	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j)
			s[j][j]=temp[i][j];
		int x;
		for(int j=1;j<=m-1;++j)
		for(int k=1;k<=m-j;++k){
			x=k+j;
			s[k][x]=max(s[k][x-1]+s[k][x-1]+temp[i][x],s[k+1][x]+s[k+1][x]+temp[i][k]);
		}
		ans=ans+s[1][m];
		ans=ans+s[1][m];
	}
	ans.print();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值