HDU 3377 Plan(插头DP-路径最大值)
2013-05-01 10:03
344 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3377
题意:给出一个n*m的数字格子。从左上角出发到达右下角,每个格子最多走一遍。求最大值。
思路:设格子是(1,1)到(n,m),将(0,1)增加下插头,将(n+1,m)格子设为可走。另外,对于没有左和上插头的格子,可以不设插头。
题意:给出一个n*m的数字格子。从左上角出发到达右下角,每个格子最多走一遍。求最大值。
思路:设格子是(1,1)到(n,m),将(0,1)增加下插头,将(n+1,m)格子设为可走。另外,对于没有左和上插头的格子,可以不设插头。
#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <set> #include <stack> #include <string> #include <map> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define abs(x) ((x)>=0?(x):-(x)) #define i64 long long #define u32 unsigned int #define u64 unsigned long long #define clr(x,y) memset(x,y,sizeof(x)) #define CLR(x) x.clear() #define ph(x) push(x) #define pb(x) push_back(x) #define Len(x) x.length() #define SZ(x) x.size() #define PI acos(-1.0) #define sqr(x) ((x)*(x)) #define FOR0(i,x) for(i=0;i<x;i++) #define FOR1(i,x) for(i=1;i<=x;i++) #define FOR(i,a,b) for(i=a;i<=b;i++) #define FORL0(i,a) for(i=a;i>=0;i--) #define FORL1(i,a) for(i=a;i>=1;i--) #define FORL(i,a,b)for(i=a;i>=b;i--) #define rush() int CC; for(scanf("%d",&CC);CC--;) #define Rush(n) while(scanf("%d",&n)!=-1) using namespace std; void RD(int &x){scanf("%d",&x);} void RD(i64 &x){scanf("%lld",&x);} void RD(u32 &x){scanf("%u",&x);} void RD(double &x){scanf("%lf",&x);} void RD(int &x,int &y){scanf("%d%d",&x,&y);} void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);} void RD(double &x,double &y){scanf("%lf%lf",&x,&y);} void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);} void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);} void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);} void RD(char &x){x=getchar();} void RD(char *s){scanf("%s",s);} void RD(string &s){cin>>s;} void PR(int x) {printf("%d\n",x);} void PR(i64 x) {printf("%lld\n",x);} void PR(u32 x) {printf("%u\n",x);} void PR(double x) {printf("%.4lf\n",x);} void PR(char x) {printf("%c\n",x);} void PR(char *x) {printf("%s\n",x);} void PR(string x) {cout<<x<<endl;} const int INF=1000000000; const int HASHSIZE=30007; const int N=1000005; int n,m,code[15],cur,pre,sx,sy; char s[100][100]; int ans; struct node { int e,next ,head[HASHSIZE]; int cnt ,state ; void init() { clr(head,-1); e=0; } void push(int s,int val) { int i,x=s%HASHSIZE; for(i=head[x];i!=-1;i=next[i]) { if(state[i]==s) { if(val>cnt[i]) cnt[i]=val; return; } } state[e]=s; cnt[e]=val; next[e]=head[x]; head[x]=e++; } }; node dp[2]; void decode(int code[],int m,int st) { int i; FORL0(i,m) code[i]=st&7,st>>=3; } int encode(int code[],int m) { int ans=0; int hash[15],i,cnt=1; clr(hash,-1); hash[0]=0; FOR0(i,m+1) { if(hash[code[i]]==-1) hash[code[i]]=cnt++; code[i]=hash[code[i]]; ans=(ans<<3)|code[i]; } return ans; } int C[15][15]; void update1(int i,int j) { int x,y,k,t,q=j==m?m-1:m; int c; FOR0(k,dp[pre].e) { decode(code,m,dp[pre].state[k]); c=dp[pre].cnt[k]; x=code[j-1]; y=code[j]; if(x&&y) { if(x!=y) { code[j-1]=code[j]=0; FOR0(t,m+1) if(code[t]==y) code[t]=x; dp[cur].push(encode(code,q),c+C[i][j]); } } else if(x||y) { if(s[i+1][j]) { code[j-1]=x+y; code[j]=0; dp[cur].push(encode(code,q),c+C[i][j]); } if(s[i][j+1]) { code[j-1]=0; code[j]=x+y; dp[cur].push(encode(code,q),c+C[i][j]); } } else if(x==0&&y==0) { dp[cur].push(encode(code,q),c); if(s[i][j+1]&&s[i+1][j]) { code[j-1]=code[j]=13; dp[cur].push(encode(code,q),c+C[i][j]); } } } } int DP() { ans=-INF; pre=0,cur=1; dp[0].init(); clr(code,0); code[1]=1; dp[0].push(encode(code,m),0); int i,j; FOR1(i,n) FOR1(j,m) { dp[cur].init(); update1(i,j); pre^=1; cur^=1; } FOR0(i,dp[pre].e) ans=max(ans,dp[pre].cnt[i]); return ans; } int main() { int num=0; Rush(n) { scanf("%d",&m); int i,j; clr(s,0); FOR1(i,n) FOR1(j,m) scanf("%d",&C[i][j]),s[i][j]=1; s[n+1][m]=1; printf("Case %d: %d\n",++num,DP()); } return 0; }
相关文章推荐
- HDU 3377 Plan 解题报告(插头DP)
- hdu 3377 Plan(插头dp)
- HDU 3377 Plan (插头DP,变形)
- HDU 3377 Plan (插头DP)
- ZOJ 3213 Beautiful Meadow(插头DP-一条路径最大值,不固定头尾)
- HDU 3377 插头dp
- dp最大路径和,注意初始化,HDU
- HDU 1693 Eat the Trees (插头DP,闭合路径)
- HDU 2571 路径权值最大 dp
- hdu 1964 Plan (插头dp)
- HDU 1506 dp求最大子矩阵 *
- hdu 3416 Marriage Match IV 最大流 最短路径
- HDU 1231——最大连续子序列(DP)
- HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)
- hdu FatMouse's Speed(DP)(打印路径)
- HDU_最大报销额(DP)
- ZOJ1733 | | HDU1159简单的DP求两个字符串最大子序列的长度,没啥好说的,照着书上敲得。
- hdu 1024 Max Sum Plus Plus (最大m子段和)(经典DP)(转)
- hdu1520 Anniversary party(最大独立集 树形dp)
- hdu 5074 相邻数和最大dp