zoukankan      html  css  js  c++  java
  • 【NOIP2007提高组】矩阵取数游戏

    本题DP+高精度即可。
    首先我们可以发现它的贡献只与行有关系,于是就分成n行,每行都做DP,然后将max加起来即可。(PS:用高精度实现)
    上标:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define mo 100000
    #define ll long long
    using namespace std;
    int n,m,c[81][81];
    struct gjd
    {
    	int a[51],top;
    }ans,f[81][81],e[81],s,d;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    gjd cheng(gjd a,int b)
    {
    	int x=0;
    	for (int i=1;i<=a.top;i++)
    	{
    		a.a[i]=a.a[i]*b+x;
    		x=a.a[i]/mo;a.a[i]%=mo;
    	}
    	while (x) a.a[++a.top]=x%mo,x/=mo;
    	return a;
    }
    
    gjd plus(gjd a,gjd b)
    {
    	int x=0;
    	memset(d.a,0,sizeof(d.a));
    	d.top=max(a.top,b.top)+1;
    	for (int i=1;i<=d.top;i++)
    	{
    		d.a[i]=a.a[i]+b.a[i]+x;
    		x=d.a[i]/mo;d.a[i]%=mo;
    	}
    	while (!d.a[d.top]) d.top--;
    	return d;
    }
    
    gjd ma(gjd a,gjd b)
    {
    	if (a.top>b.top) return a;
    	else if (a.top<b.top) return b;
    	for (int i=a.top;i>0;i--)
    		if (a.a[i]>b.a[i]) return a;
    		else if (a.a[i]<b.a[i]) return b;
    	return a;
    }
    
    int main()
    {
    	freopen("game.in","r",stdin);
    	freopen("game.out","w",stdout);
    	n=read(),m=read();
    	e[0].a[1]=1,e[0].top=1;
    	for (int i=1;i<=m;i++)
    		e[i]=cheng(e[i-1],2);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++) c[i][j]=read();
    	for (int i=1;i<=n;i++)
    	{
    		memset(f,0,sizeof(f));
    		
    		f[0][m].a[1]=0,f[0][m].top=1;
    		for (int j=1;j<=m;j++)
    		{
    			f[j][m]=ma(f[j][m],plus(f[j-1][m],cheng(e[j],c[i][j])));
    			for (int k=m-1;k>=j;k--)
    				f[j][k]=ma(f[j][k],ma(plus(f[j-1][k],cheng(e[m-k+j],c[i][j])),plus(f[j][k+1],cheng(e[m-k+j],c[i][k+1]))));
    		}
    		for (int j=m-1;j>=0;j--)
    		{
    			f[0][j]=ma(f[0][j],plus(f[0][j+1],cheng(e[m-j],c[i][j+1])));
    			for (int k=1;k<=j;k++)
    				f[k][j]=ma(f[k][j],ma(plus(f[k-1][j],cheng(e[m-j+k],c[i][k])),plus(f[k][j+1],cheng(e[m-j+k],c[i][j+1]))));
    		}
    		memset(s.a,0,sizeof(s.a));
    		s.top=0;
    		for (int j=0;j<=m;j++)
    			s=ma(s,f[j][j]);
    		ans=plus(ans,s);
    	}
    	printf("%d",ans.a[ans.top]);
    	for (int i=ans.top-1;i>0;i--)
    		printf("%05d",ans.a[i]);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    如何使用 SPICE client (virt-viewer) 来连接远程虚拟机桌面?
    小米手机会不会更好
    5年一梦
    每天进步一点点——分布式文件系统下的本地缓存
    iOS开发中的NSDateFormatter日期格式解析总结
    IOS假设将一个十六进制的color转换成UIColor,非常有用
    HH实习(hpu1287)(斐波那契运用)
    学习用CMake来编写Qt程序
    【MFC设置静态文本框背景为透明】
    排序(3)---------冒泡排序(C语言实现)
  • 原文地址:https://www.cnblogs.com/jz929/p/11817805.html
Copyright © 2011-2022 走看看