BZOJ2310

来源:互联网 发布:江湖家政o2o源码下载 编辑:程序博客网 时间:2024/06/06 03:59

2310: ParkII

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 86  Solved: 34
[Submit][Status][Discuss]

Description

Hnoi2007-Day1有一道题目 Park:给你一个 m * n 的矩阵,每个矩阵内有个
权值V(i,j) (可能为负数),要求找一条回路,使得每个点最多经过一次,并且经过
的点权值之和最大,想必大家印象深刻吧. 
无聊的小 C 同学把这个问题稍微改了一下:要求找一条路径,使得每个点
最多经过一次,并且点权值之和最大,如果你跟小 C 一样无聊,就麻烦做一下
这个题目吧.

Input

第一行 m, n,接下来 m行每行 n 个数即. 
V( i,j)

Output

一个整数表示路径的最大权值之和.

Sample Input

2 3
1 -2 1
1 1 1

Sample Output

5
【数据范围】
30%的数据,n≤6.
100%的数据,m<=100,n ≤ ≤8.
注意:路径上有可能只有一个点.



恶心的杀头DP...
可以看cdq的<基于连通性状态压缩的动态规划问题>
PS:我的代码不知道比mcfx短到哪里去了...


#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define maxp 2000000#define yjq 32767#define bit(x) ((x)<<1)using namespace std;int a[110][10];int nxt[maxp],head[yjq+10],tot[2],n,m,nn,mm;int status[2][maxp],ptr,nptr;int dp[2][maxp],ans=-1<<30;void add(int x,int s){    int p=x&yjq;    for(int t=head[p];t;t=nxt[t])        if(status[ptr][t]==x){            dp[ptr][t]=max(dp[ptr][t],s);            return ;        }    tot[ptr]++;    status[ptr][tot[ptr]]=x;    dp[ptr][tot[ptr]]=s;    nxt[tot[ptr]]=head[p],head[p]=tot[ptr];}int conn(int x,int j,int k){    if(k==1){        int b=1;        for(int i=j+1;i<=m;++i){            int p=(x>>bit(i))&3;            if(p==1)b++;            else if(p==2)b--;            if(b==0)return i;        }    } else if(k==2){        int b=1;        for(int i=j-2;i>=0;--i){            int p=(x>>bit(i))&3;            if(p==2)b++;            else if(p==1)b--;            if(b==0)return i;        }    }    return -1;}bool check0(int x){//for(int i=0;i<=m;++i)if(((x>>bit(i))&3)==1)return false;//return true;//return ()}int replace(int x,int j,int to){int p=(x>>bit(j))&3;return x-(p<<bit(j))+(to<<bit(j));}int main(){//freopen("in.txt","r",stdin);scanf("%d%d",&n,&m);for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)scanf("%d",&a[i][j]),ans=max(ans,a[i][j]);ptr=1,nptr=0,tot[ptr]=1;for(int i=1;i<=n;++i){for(int j=1;j<=tot[ptr];++j)status[ptr][j]<<=2;for(int j=1;j<=m;++j){swap(ptr,nptr);tot[ptr]=0;//printf("[%d]",tot[nptr]);memset(head,0,sizeof(head));for(int k=1,c1;k<=tot[nptr];++k){int st=status[nptr][k];if(st>=(1<<bit(m+1)))continue;int x=dp[nptr][k];int p=(st>>bit(j-1))&3,q=(st>>bit(j))&3;int xt=st-(p<<bit(j-1))-(q<<bit(j));if(p==0&&q==0){add(st,x);add(st+(3<<bit(j-1)),x+a[i][j]);add(st+(3<<bit(j)),x+a[i][j]);add(st+(1<<bit(j-1))+(2<<bit(j)),x+a[i][j]);} else if(p==0&&q>0){add(st,x+a[i][j]);add(st+(q<<bit(j-1))-(q<<bit(j)),x+a[i][j]);if(q!=3)add(replace(st-(q<<bit(j)),conn(st,j,q),3),x+a[i][j]);else if(!xt)ans=max(ans,x+a[i][j]);} else if(p>0&&q==0){add(st,x+a[i][j]);add(st-(p<<bit(j-1))+(p<<bit(j)),x+a[i][j]);if(p!=3)add(replace(st-(p<<bit(j-1)),conn(st,j,p),3),x+a[i][j]);else if(!xt)ans=max(ans,x+a[i][j]);} else if(p==q&&p!=3){ add(replace(st-(p<<bit(j-1))-(q<<bit(j)),conn(st,j,p),p),x+a[i][j]); } else if(p==2&&q==1){ add(st-(p<<bit(j-1))-(q<<bit(j)),x+a[i][j]); }else if(p==3&&q==3){ if(!xt)ans=max(ans,x+a[i][j]); } else if(p==3&&q!=3){ add(replace(st-(p<<bit(j-1))-(q<<bit(j)),conn(st,j,q),3),x+a[i][j]); }else if(p!=3&&q==3){ add(replace(st-(p<<bit(j-1))-(q<<bit(j)),conn(st,j,p),3),x+a[i][j]); }}}}    printf("%d",ans); }



0 0
原创粉丝点击