vijos P1143三取方格数

描述

设有N*N的方格图,我们将其中的某些方格填入正整数,
而其他的方格中放入0。

某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。

在走过的路上,他取走了方格中的数。(取走后方格中数字变为0)
此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。

格式

输入格式

第一行:N (4<=N<=20)
接下来一个N*N的矩阵,矩阵中每个元素不超过80,不小于0

输出格式

一行,表示最大的总和。

样例1

样例输入1

4
1 2 3 4
2 1 3 4
1 2 3 4
1 3 2 4

样例输出1

39

题解

想法一:无脑费用流。
#include
#include
#include
#include
#include
#include
#define T 802
#define inf 1<<30
using namespace std;
int n,m,zz=1,head[805];
struct bian{int frm,to,nx,v,c;} e[10002];
int dis[805],pd[805],q[805],from[805],ans;
void insert(int x,int y,int z,int c)
{
	zz++; e[zz].to=y; e[zz].frm=x; e[zz].v=z;
	e[zz].c=c; e[zz].nx=head[x]; head[x]=zz;
	zz++; e[zz].to=x; e[zz].frm=y; e[zz].v=0;
	e[zz].c=-c; e[zz].nx=head[y]; head[y]=zz;
}
void init()
{
	scanf("%d",&n);
	int i,j,x;
	for(i=1;i<=n;i++)
	for(j=1;j<=n;j++)
	   {scanf("%d",&x);
	    insert((i-1)*n+j,(i-1)*n+j+n*n,1,x);
	    insert((i-1)*n+j,(i-1)*n+j+n*n,3,0);
	    if(i0&&dis[p]
想法二:四维dp:f[i][j][k][l]表示走第i步时,第一次,第二次,第三次分别走到第j,k,l列的最优情况。
#include
#include
#include
#include
#include
#include
using namespace std;
int n,m,a[22][22],f[42][22][22][22];
void init()
{
	scanf("%d",&n);
	int i,j;
	for(i=1;i<=n;i++)
	for(j=1;j<=n;j++)
	scanf("%d",&a[i][j]);
}
void dp()
{
	int i,j,k,l;
	f[1][1][1][1]=a[1][1];
	for(i=2;i<=n+n-1;i++)
	for(j=1;j<=min(i,n);j++)
	for(k=1;k<=min(i,n);k++)
	for(l=1;l<=min(i,n);l++)
	   {f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j-1][k][l]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k-1][l]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l-1]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j-1][k-1][l]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k-1][l-1]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j-1][k][l-1]);
	    f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j-1][k-1][l-1]);
	    if(j==k&&k==l)
	       f[i][j][k][l]+=a[i-j+1][j];
	    else if(j==k)
	       f[i][j][k][l]+=a[i-j+1][j]+a[i-l+1][l];
	    else if(j==l)
	       f[i][j][k][l]+=a[i-j+1][j]+a[i-k+1][k];
	    else if(l==k)
	       f[i][j][k][l]+=a[i-j+1][j]+a[i-l+1][l];
	    else
	       f[i][j][k][l]+=a[i-j+1][j]+a[i-l+1][l]+a[i-k+1][k];
	   }
	printf("%d\n",f[n+n-1][n][n][n]);
}
int main()
{
	init(); dp();
	return 0;
}

你可能感兴趣的:(动态规划,图论)