• poj 1185 & hdu 4539(状态压缩DP)


    这两道题如出一辙,只是判断有效状态有一点小差异。

    每一行的状态只与前面两行的状态有关,每行可以压缩为二进制的集合,设状态dp[i][j][k]为第i行为集合j,第i-1行为集合k,

    得出状态方程dp[i][j][k] = max{dp[i-1][k][r]+cnt[j]  | 状态i,j,k要能够共存}(cnt[j]为j在二进制下的1的个数,即士兵数)。第一维可以压缩为2,即两种状态交替进行。

    对于每一行可能出现的组合,可以先预处理出每一种有效状态。

    poj 1185
      1 /*
      2  *Author:       Zhaofa Fang
      3  *Created time: 2013-03-30-11.54
      4  *Language:     C++
      5  */
      6 #include <cstdio>
      7 #include <cstdlib>
      8 #include <sstream>
      9 #include <iostream>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <string>
     14 #include <utility>
     15 #include <vector>
     16 #include <queue>
     17 #include <stack>
     18 #include <map>
     19 #include <set>
     20 using namespace std;
     21 
     22 typedef long long ll;
     23 #define DEBUG(x) cout<< #x << ':' << x << endl
     24 #define REP(i,n) for(int i=0;i < (n);i++)
     25 #define REPD(i,n) for(int i=(n-1);i >= 0;i--)
     26 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
     27 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
     28 #define PII pair<int,int>
     29 #define PB push_back
     30 #define MP make_pair
     31 #define ft first
     32 #define sd second
     33 #define lowbit(x) (x&(-x))
     34 #define INF (1<<30)
     35 
     36 int maz[105],f[65],cnt[65];
     37 char str[105][15];
     38 int dp[2][65][65];
     39 int len;
     40 
     41 
     42 bool ok(int x){
     43     if(x&(x<<1))return false;
     44     if(x&(x<<2))return false;
     45     return true;
     46 }
     47 int count(int x){
     48     int res=0;
     49     while(x>0){
     50         res+=(x&1);
     51         x>>=1;
     52     }
     53     return res;
     54 }
     55 void fun(int m){
     56     REP(i,(1<<m)){
     57         if(ok(i)){
     58             f[len]=i;
     59             cnt[len++]=count(i);
     60         }
     61     }
     62 }
     63 int main(){
     64     //freopen("in","r",stdin);
     65     //freopen("out","w",stdout);
     66     int n,m;
     67     while(~scanf("%d%d",&n,&m)){
     68         memset(dp,-1,sizeof(dp));
     69         memset(f,0,sizeof(f));
     70         REP(i,n){
     71             scanf("%s",str[i]);
     72             maz[i]=0;
     73             REP(j,m){
     74                 if(str[i][j]=='H')maz[i]|=(1<<j);
     75             }
     76         }
     77         int now=1;
     78         len=0;
     79         fun(m);//枚举有效状态
     80         REP(i,len)if(!(f[i]&maz[0]))dp[now][i][0]=cnt[i];
     81         FOR(i,1,n-1){
     82             now^=1;
     83             REP(a,len){
     84                 if(maz[i]&f[a])continue;
     85                 REP(b,len){
     86                     if(f[a]&f[b])continue;
     87                     REP(c,len){
     88                         if((f[a]&f[c])||(f[b]&f[c]))continue;
     89                         if(dp[now^1][b][c]==-1)continue;
     90                         dp[now][a][b]=max(dp[now][a][b],dp[now^1][b][c]+cnt[a]);
     91                     }
     92                 }
     93             }
     94         }
     95         int ans=0;
     96         REP(i,len)REP(j,len)ans=max(ans,dp[now][i][j]);
     97         printf("%d\n",ans);
     98     }
     99     return 0;
    100 }
    hdu 4539
      1 /*
      2  *Author:       Zhaofa Fang
      3  *Created time: 2013-03-30-11.54
      4  *Language:     C++
      5  */
      6 #include <cstdio>
      7 #include <cstdlib>
      8 #include <sstream>
      9 #include <iostream>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <string>
     14 #include <utility>
     15 #include <vector>
     16 #include <queue>
     17 #include <stack>
     18 #include <map>
     19 #include <set>
     20 using namespace std;
     21 
     22 typedef long long ll;
     23 #define DEBUG(x) cout<< #x << ':' << x << endl
     24 #define REP(i,n) for(int i=0;i < (n);i++)
     25 #define REPD(i,n) for(int i=(n-1);i >= 0;i--)
     26 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
     27 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
     28 #define PII pair<int,int>
     29 #define PB push_back
     30 #define MP make_pair
     31 #define ft first
     32 #define sd second
     33 #define lowbit(x) (x&(-x))
     34 #define INF (1<<30)
     35 
     36 int maz[170],f[170],cnt[170];
     37 int dp[2][170][170];
     38 int len;
     39 
     40 
     41 bool ok(int x){
     42     if(x&(x<<2))return false;
     43     return true;
     44 }
     45 int count(int x){
     46     int res=0;
     47     while(x>0){
     48         res+=(x&1);
     49         x>>=1;
     50     }
     51     return res;
     52 }
     53 void fun(int m){
     54     REP(i,(1<<m)){
     55         if(ok(i)){
     56             f[len]=i;
     57             cnt[len++]=count(i);
     58         }
     59     }
     60 }
     61 int main(){
     62     //freopen("in","r",stdin);
     63     //freopen("out","w",stdout);
     64     int n,m;
     65     while(~scanf("%d%d",&n,&m)){
     66         memset(dp,-1,sizeof(dp));
     67         memset(f,0,sizeof(f));
     68         REP(i,n){
     69             maz[i]=0;
     70             REP(j,m){
     71                 int x;scanf("%d",&x);
     72                 if(!x)maz[i]|=(1<<j);
     73             }
     74         }
     75         int now=1;//用于压空间
     76         len=0;
     77         fun(m);//枚举有效状态
     78         REP(i,len)if(!(f[i]&maz[0]))dp[now][i][0]=cnt[i];
     79         FOR(i,1,n-1){
     80             now^=1;
     81             REP(a,len){
     82                 if(maz[i]&f[a])continue;
     83                 REP(b,len){
     84                     if(f[a]&(f[b]<<1))continue;
     85                     if(f[a]&(f[b]>>1))continue;
     86                     int tmp=0;
     87                     REP(c,len){
     88                         if(f[b]&(f[c]<<1))continue;
     89                         if(f[b]&(f[c]>>1))continue;
     90                         if(f[a]&f[c])continue;
     91                         if(dp[now^1][b][c]==-1)continue;
     92                         dp[now][a][b]=max(dp[now][a][b],dp[now^1][b][c]+cnt[a]);
     93                     }
     94                 }
     95             }
     96         }
     97         int ans=0;
     98         REP(i,len)REP(j,len)ans=max(ans,dp[now][i][j]);
     99         printf("%d\n",ans);
    100     }
    101     return 0;
    102 }
    by Farmer
  • 相关阅读:
    我的书单
    说说IUnitOfWork~Linq to Sql与EntityFrameworks中的SubmtChanges()发生了什么事
    说说IUnitOfWork~认识IUnitOfWork,为什么要出现IUnitOfWork接口
    LINQtoSQL那点事~关于延时加载的性能,微软给出了不错的解决方案
    数据结构~站点地图其实是一颗树
    说说IUnitOfWork~方法完整性与统一提交不冲突
    递归 解剖
    Java Socket一对一聊天
    转:浅谈c++容器
    Java JList 使用
  • 原文地址:https://www.cnblogs.com/fzf123/p/2991102.html
Copyright © 2020-2023  润新知