当前位置:编程学习 > C/C++ >>

POJ - 1185 跑兵阵地 状态压缩DP

    状态压缩DP...很简单了...一行最多10个...用1代表放炮兵..0代表不放...每行的状态最多1024种..并且还要合法..这样一来..一行的状态最多60种了...

    能影响到当前行的只有上两行..所以用三维的DP...dp[t][x1][x2]....t代表哪一层了...x1代表上一层的状态..x2代表当前层的状态...

    dp[t][x1][x2]= max ( dp[t-1][y][x1] + cnt[x2]) ...y是t-2层的状态...cnt是当前层状态的炮兵数,也就是1的数量...这里看出约束条件..就是状态x1,x2,y不能冲突...

 


Program:


[cpp]
#include<iostream>  
#include<cmath>  
#include<stack>  
#include<queue>  
#include<set>  
#include<algorithm>  
#include<stdio.h>  
#include<string.h>  
#define ll long long  
#define oo 1000000007  
using namespace std;    
int n,m,a[105],anum; 
char arc[105][12]; 
int cnt[65],dp[105][65][65]; 
bool ok1(int x)   // 判断当前状态是否合法  

       int p,i; 
       p=-10;  
       while (x) 
       { 
             i++; 
             if (x%2) 
             { 
                   if (i-p<=2) return false; 
                   p=i; 
             } 
             x/=2; 
       }        
       return true; 

bool ok2(int t,int x)  //判断当前状态能否放在当前的图上  

       int i;  
       for (i=m;i>=1 && x;i--) 
       { 
             if (x%2 && arc[t][i]=='H') return false; 
             x/=2; 
       } 
       return true; 

bool ok3(int y,int x) //判断状态y在上,状态x在下,能否不冲突  

       while (y && x) 
       { 
             if (y%2 && x%2) return false; 
             y/=2;  x/=2; 
       } 
       return true; 

int main() 
{        
       int i,t,j,x,ans; 
       while (~scanf("%d%d",&n,&m)) 
       {  
               anum=0; 
               a[0]=0; 
               for (i=0;i<(1<<m);i++) 
                  if (ok1(i))  
                  { 
                          a[++anum]=i; 
                          cnt[anum]=0; 
                          j=i; 
                          while (j) 
                          { 
                                 j=j&(j-1); 
                                 cnt[anum]++; 
                          } 
                  } 
               for (i=0;i<=n;i++) gets(arc[i]+1); 
               memset(dp,0,sizeof(dp)); 
               for (i=1;i<=anum;i++) 
                 if (ok2(1,a[i]))  dp[1][0][i]=cnt[i];   
               for (t=2;t<=n;t++) 
                  for (i=0;i<=anum;i++) 
                    if (ok2(t,a[i])) 
                      for (j=0;j<=anum;j++) 
                        if (ok2(t-1,a[j]) && ok3(a[j],a[i])) 
                          for (x=0;x<=anum;x++) 
                            if (dp[t][j][i]<dp[t-1][x][j]+cnt[i] && ok3(a[x],a[i])) 
                                dp[t][j][i]=dp[t-1][x][j]+cnt[i]; 
    &nbs

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,