zoukankan      html  css  js  c++  java
  • POJ 1185 状压DP

    legal[] 保存所有在当前行可显示的状态,由dfs得到,len[]保存legal[]对应下标状态中的 1 的个数 , 也就是放置炮台的个数

    state[i] 表示第 i 行这块区域的土地情况,H表示 1 ,P表示 0

    那么每次加入一个legal状态  都要符合 !(legal[i] & state[k])

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 int dp[105][80][80],vis[12],state[105],legal[80],len[80];
     6 int cnt,n,m;
     7 
     8 void dfs(int u , int _state , int l)
     9 {
    10     if(u > m){
    11         legal[++cnt] = _state;
    12         len[cnt] = l;
    13         return;
    14     }
    15     int flag = 1;
    16     if(u>1){
    17         if(vis[u-1]) flag=0;
    18     }
    19     if(u>2){
    20        if(vis[u-2]) flag=0;
    21     }
    22     if(flag){
    23         vis[u] = 1;
    24         dfs(u+1 , _state<<1|1 , l+1);
    25         vis[u] = 0;
    26     }
    27     dfs(u+1 , _state<<1 , l);
    28 }
    29 
    30 void DP()
    31 {
    32     for(int k=1;k<=n;k++){
    33         for(int i=1;i<=cnt;i++){
    34             for(int j=1;j<=cnt;j++){
    35                 if(k == 1 && !(state[k] & legal[i])){
    36                     dp[k][j][i] = len[i];
    37                 }
    38                 for(int t=1;t<=cnt;t
    39                 ++){
    40                     if(!(state[k] & legal[i]) && !(legal[i] & legal[j]) && !(legal[i] & legal[t]) && !(legal[t] & legal[j])){
    41                         dp[k][j][i] = max(dp[k][j][i] , dp[k-1][t][j] + len[i]);
    42                     }
    43                 }
    44             }
    45         }
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     //freopen("POJ1185.test","rb",stdin);
    52     char c;
    53     while(~scanf("%d%d",&n,&m)){
    54         for(int i=1;i<=n;i++){
    55             state[i] = 0;
    56             for(int j=1 ; j<=m ; j++){
    57                 cin>>c;
    58                 if(c == 'H') state[i] = state[i]<<1|1;
    59                 else state[i] = state[i]<<1;
    60             }
    61         }
    62         cnt=0;
    63         memset(vis,0,sizeof(vis));
    64         dfs(1,0,0);
    65 
    66         memset(dp,0,sizeof(dp));
    67         DP();
    68 
    69         int ans=0;
    70         for(int i=1;i<=cnt;i++){
    71             for(int j=1;j<=cnt;j++){
    72                 ans = max(dp[n][i][j] , ans);
    73             }
    74         }
    75         cout<<ans<<endl;
    76     }
    77 
    78     return 0;
    79 }
  • 相关阅读:
    windows下大数据开发环境搭建(3)——Scala环境搭建
    windows下大数据开发环境搭建(1)——Java环境搭建
    windows下大数据开发环境搭建(2)——Hadoop环境搭建
    I/O复用
    SuRF : Practical Range Query Filtering with Fast Succinct Tries
    信号处理
    进程间通信
    简易内存分配器的实现
    socket编程(C++)
    C++—程序的内存分区
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4058003.html
Copyright © 2011-2022 走看看