【HDOJ】【3377】Plan

插头DP



  sigh……其实思路很简单的= =就多加一种转移:从(0,0)->(0,0),也就是不走这个格子……

  初始状态就是第一格有一个左插头= =结束状态可以让(n,m)这个位置可以走到(n+1,m),这样就符合题意了= =

  然后一个大坑出现:

    转移时不能随意修改sum值!!因为一个状态两次转移的话,第一次修改了sum值,第二次的转移就会出错!!

    http://blog.csdn.net/xingyeyongheng/article/details/24499375 我还是看了这篇博客才幡然醒悟!

  1 //BZOJ 3377
  2 #include<cmath>
  3 #include<vector>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<iostream>
  8 #include<algorithm>
  9 #define rep(i,n) for(int i=0;i<n;++i)
 10 #define F(i,j,n) for(int i=j;i<=n;++i)
 11 #define D(i,j,n) for(int i=j;i>=n;--i)
 12 #define pb push_back
 13 #define CC(a,b) memset(a,b,sizeof(a))
 14 using namespace std;
 15 int getint(){
 16     int v=0,sign=1; char ch=getchar();
 17     while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();}
 18     while(isdigit(ch))  {v=v*10+ch-‘0‘; ch=getchar();}
 19     return v*sign;
 20 }
 21 const int N=1e7+10,INF=~0u>>2;
 22 const double eps=1e-8;
 23 /*******************template********************/
 24 const int M=100007;
 25 typedef long long LL;
 26 int mp[12][12];
 27 bool mmp[12][12];
 28 int n,m,k;
 29 int tot[2],bit[12],hash[M],state[2][M];
 30 LL dp[2][M],ans;
 31
 32 void init(){
 33     CC(mp,0);
 34     CC(mmp,0);
 35     char ch;
 36     F(i,1,n) F(j,1,m) {scanf("%d",&mp[i][j]); mmp[i][j]=1;}
 37     mmp[n+1][m]=1;
 38     F(i,0,1) F(j,0,M-1) dp[i][j]=-INF;
 39     tot[0]=1; ans=-INF;
 40     k=0;
 41     dp[0][1]=mp[1][1];
 42     state[0][1]=1;
 43 }
 44 void hash_in(int s,LL sum){
 45     int p=s%M;
 46     while(hash[p]){
 47         if (state[k][hash[p]]==s){
 48             dp[k][hash[p]]=max(dp[k][hash[p]],sum);
 49             return;
 50         }
 51         p++;
 52         if (p==M) p=0;
 53     }
 54     hash[p]=++tot[k];
 55     state[k][hash[p]]=s;
 56     dp[k][hash[p]]=sum;
 57 }
 58 #define in hash_in(s,sum)
 59 void work(){
 60     F(i,1,n){
 61         F(j,1,m){
 62             k^=1;
 63             tot[k]=0;
 64             CC(hash,0);
 65             F(u,1,tot[1-k]){
 66                 int s=state[1-k][u];
 67                 LL sum=dp[1-k][u];
 68                 int p=(s>>bit[j-1])&3,q=(s>>bit[j])&3,d=(s>>bit[j+1])&3;
 69                 if (!p && !q){
 70                     in;
 71                     if (!mmp[i+1][j] || !mmp[i][j+1]) continue;
 72                     s=s^(1<<bit[j-1])^(1<<bit[j]<<1);
 73                     sum=sum+mp[i][j]+mp[i+1][j];
 74                     if (!d) sum+=mp[i][j+1];
 75                     in;
 76                 }else if(!p && q){
 77                     if (mmp[i][j+1]){
 78 //                        if (!d) sum+=mp[i][j+1];
 79                         if (!d) hash_in(s,sum+mp[i][j+1]);
 80                         else in;
 81                     }
 82                     if (mmp[i+1][j]){
 83                         s=s^q*(1<<bit[j])^q*(1<<bit[j-1]);
 84                         sum+=mp[i+1][j]; in;
 85                     }
 86                 }else if(p && !q){
 87                     if (mmp[i+1][j]) hash_in(s,sum+mp[i+1][j]);
 88                     if (mmp[i][j+1]){
 89                         s=s^p*(1<<bit[j])^p*(1<<bit[j-1]);
 90                         if (!d)sum+=mp[i][j+1];
 91                         in;
 92                     }
 93                 }else if(p+q==2){
 94                     int nd=1;
 95                     F(u,j+1,m){
 96                         int w=(s>>bit[u])&3;
 97                         if (w==1) nd++;
 98                         if (w==2) nd--;
 99                         if (!nd){ s-=1<<bit[u]; break; }
100                     }
101                     s=s^(1<<bit[j-1])^(1<<bit[j]),in;
102                 }else if(p+q==4){
103                     int nd=1;
104                     D(u,j-2,1){
105                         int w=(s>>bit[u])&3;
106                         if (w==2) nd++;
107                         if (w==1) nd--;
108                         if (!nd){ s+=1<<bit[u]; break; }
109                     }
110                     s=s^(1<<bit[j-1]<<1)^(1<<bit[j]<<1),in;
111                 }else if(p==2 && q==1){
112                     s=s^(1<<bit[j-1]<<1)^(1<<bit[j]),in;
113                 }else if(p==1 && q==2) continue;
114             }
115         }
116         F(j,1,tot[k]) state[k][j]<<=2;
117     }
118     F(i,1,tot[k]) ans=max(ans,dp[k][i]);
119 }
120 int main(){
121 #ifndef ONLINE_JUDGE
122     freopen("3377.in","r",stdin);
123 //    freopen("output.txt","w",stdout);
124 #endif
125     F(i,0,10) bit[i]=i<<1;
126     int T=0;
127     while(scanf("%d%d",&n,&m)!=EOF){
128         init();
129         work();
130         printf("Case %d: %lld\n",++T,ans);
131     }
132     return 0;
133 }

时间: 2024-11-10 01:26:51

【HDOJ】【3377】Plan的相关文章

【HDOJ图论题集】【转】

1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How Many Tables 基础并查集★ 4 1272 小希的迷宫 基础并查集★ 5 1325&&poj1308 Is It A Tree? 基础并查集★ 6 1856 More is better 基础并查集★ 7 1102 Constructing Roads 基础最小生成树★ 8 1232

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

【HDOJ 4768】 Flyer (等差数列+二分)

[HDOJ 4768] Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2022    Accepted Submission(s): 743 Problem Description The new semester begins! Different kinds of student soc

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t