noip2007 矩阵取数

简单的DP+高精,


高精通过4个int64压位,效率还好,高精度的代价是4,小的忽略不计。


type
num=array[1..5]of int64;
const
mo=100000000;
var
n,m,i,j,l,k:longint;
a:array[1..80]of longint;
two:array[0..80] of num;
f:array[1..80,1..80] of num;
ans,t1,t2:num;
function add_btb(a,b:num):num;
var
	c:num;
	i:longint;
	x:int64;
begin
	x:=0;
	for i:=1 to 4 do begin
		c[i]:=a[i]+b[i]+x;
		x:=c[i] div mo;
		c[i]:=c[i] mod mo;
	end;
	add_btb:=c;
end;
function mul_btc(a:num;b:int64):num;
var
	i:longint;
	c:num;
	x:int64;
begin
	x:=0;
	fillchar(c,sizeof(c),0);
	for i:=1 to 4 do begin
		c[i]:=a[i]*b+x;
		x:=c[i] div mo;
		c[i]:=c[i] mod mo;
	end;
	mul_btc:=c;
end;
function max(a,b:num):num;
var
	i:longint;
begin
	for i:=4 downto 1 do begin
		if a[i]=b[i] then continue;
		if a[i]>b[i] then exit(a) else exit(b);
	end;
end;


procedure print(a:num);
var i,k:longint;
begin
	for k:=4 downto 1 do if a[k]<>0 then break;
	for i:=k downto 1 do begin
		if i<>k then begin
			if a[i]<10000000 then write(0);
			if a[i]<1000000 then write(0);
			if a[i]<100000 then write(0);
			if a[i]<10000 then write(0);
			if a[i]<1000 then write(0);
			if a[i]<100 then write(0);
			if a[i]<10 then write(0);
		end;
		write(a[i]);
	end;
	writeln;
end;
begin
	readln(n,m);
	two[0][1]:=1;
	for i:=1 to m do two[i]:=mul_btc(two[i-1],2);
	for k:=1 to n do begin
		for i:=1 to m do begin
			read(a[i]);
			f[i,i]:=mul_btc(two[m],a[i]);
		end;
		for l:=1 to m-1 do
			for i:=1 to m-l do begin
				j:=i+l;
				t1:=add_btb(f[i+1,j],mul_btc(two[m-j+i],a[i]));
				t2:=add_btb(f[i,j-1],mul_btc(two[m-j+i],a[j]));
				f[i,j]:=max(t1,t2);
			end;
		ans:=add_btb(ans,f[1,m]);
	end;
	print(ans);
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值