BZOJ2310
来源:互联网 发布:江湖家政o2o源码下载 编辑:程序博客网 时间:2024/06/06 03:59
2310: ParkII
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 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
1 -2 1
1 1 1
Sample Output
5
【数据范围】
30%的数据,n≤6.
100%的数据,m<=100,n ≤ ≤8.
注意:路径上有可能只有一个点.
【数据范围】
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
- BZOJ2310
- 【bzoj2310】ParkII 插头dp
- [bzoj2310][HAOI2011]Problem b
- BZOJ2310 parkii (插头DP)
- bzoj1187: [HNOI2007]神奇游乐园 & bzoj2310: ParkII
- Redis入门 (CentOS7 + Redis-3.2.1)
- Latex--入门系列二
- 用 _findfirst 和 _findnext 查找文件
- mvc 4 razor语法讲解和使用
- 14.文件上传(小案例及解析)
- BZOJ2310
- 几张图简单说明Node结构
- JavaScript初步学习—函数表达式
- 发布的QT程序无法显示图标和图片的问题
- 安利AutoValue第二波
- javascript脚本化CSS系列和封装兼容方法的getStyle(obj, prop)方法
- __VA_ARGS__用法
- c++ 数据结构 队列应用之电路布线
- Ubuntu 16.04 下快速搭建 LNMP环境