zoukankan      html  css  js  c++  java
  • poj 1185(状压dp)

    题目链接:http://poj.org/problem?id=1185

    思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到递推方程:dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+num[j]);(其中num[j]为该状态下可以放置的士兵的个数。至于具体怎么分析,这位大牛讲的很清楚:http://www.cnblogs.com/scau20110726/archive/2013/02/27/2935256.html

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int dp[111][77][77];
     8 int row[111];
     9 int s[1<<12];//保存所有士兵合法的状态
    10 int num[1<<12];
    11 int n,m,ans,state;
    12 char str[111];
    13 
    14 int Get_Num(int x)
    15 {
    16     int cnt=0;
    17     while(x>0){
    18         cnt++;
    19         x=x&(x-1);
    20     }
    21     return cnt;
    22 }
    23 
    24 int main()
    25 {
    26     while(~scanf("%d%d",&n,&m)){
    27         memset(row,0,sizeof(row));
    28         memset(dp,0,sizeof(dp));
    29         memset(num,0,sizeof(num));
    30         for(int i=0;i<n;i++){
    31             scanf("%s",str);
    32             for(int j=0;j<m;j++){
    33                 if(str[j]=='H')row[i]=(row[i]<<1)|1;
    34                 else row[i]<<=1;
    35             }
    36         }
    37         state=0;
    38         for(int i=0;i<(1<<m);i++){
    39             if((i&(i<<1))||(i&(i<<2)))continue;
    40             s[state]=i; //合法状态
    41             num[state++]=Get_Num(i);//可以放置的士兵个数
    42         }
    43         for(int i=0;i<state;i++){
    44             if(s[i]&row[0])continue;
    45             dp[0][i][0]=num[i];
    46         }
    47         for(int i=1;i<n;i++){
    48             for(int j=0;j<state;j++){
    49                 if(row[i]&s[j])continue;
    50                 for(int k=0;k<state;k++){
    51                     if(s[j]&s[k])continue;  //i行与i-1行士兵相互攻击
    52                     for(int l=0;l<state;l++){
    53                         if(s[j]&s[l])continue;//i行与i-2行士兵相互攻击
    54                         if(s[k]&s[l])continue;//i-1行与i-2行士兵相互攻击
    55                         dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+num[j]);
    56                     }
    57                 }
    58             }
    59         }
    60         ans=0;
    61         for(int i=0;i<state;i++){
    62             for(int j=0;j<state;j++){
    63                 ans=max(ans,dp[n-1][i][j]);
    64             }
    65         }
    66         printf("%d
    ",ans);
    67     }
    68     return 0;
    69 }
    70 
    71                         
    72 
    73             
    74 
    75 
    76                 
    View Code
  • 相关阅读:
    JZ2440开发板开发环境搭建
    20180730-宿主机开发环境搭建
    20180319-双网卡电脑同时上内外网
    嵌入式ARM板子起步
    20180127-服务器开发环境搭建
    Pool多进程示例
    Python基础-day01
    解释型语言与编译型语言
    C 编译过程浅析
    博客奇谭
  • 原文地址:https://www.cnblogs.com/wally/p/3292351.html
Copyright © 2011-2022 走看看