poj1185

这道题目和poj3254属于类型题,思想和方法上都类似,首先,自己做麻烦的第一点在于 a&b 两个十进制的数本身就可以判断两列是否有炮兵对打,而不用像我一开始想象的把十进制转成二进制,再用二进制进行判断,这个已经帮你弄好了。
第二点,本身状态也没有那么多。最多是1024个,再加上用if((i&i<<1)||(i&i<<2)) (这个判断简直了)之后就剩了大概六十个左右好像是。所以将这些合理的状态记录下来,这样的思路就能够想到了。
第三点,判断状态 哪一行是属于第几个状态,这点也很好。
剩下的就是状态dp自己的事了,什么这一行的值只和前两行有关什么的。

#include <iostream> 
#include <vector> 
#include <string> 
#include <cstring> 
#include <algorithm> 
#include <cmath> 
#pragma warning(disable:4996) 
using namespace std;  

int hang[110];//hang[i]表示第i行的初始状态 
int state[80];// 
int solider[80];  
int dp[110][80][80];  
int row,col,i,j,k,h,he;  
char pb_state[15];  

int main()  
{  
    cin>>row>>col;  

    memset(hang,0,sizeof(hang));  
    memset(dp,0,sizeof(dp));  
    memset(solider,0,sizeof(solider));  
    memset(state,0,sizeof(state));  

    for(i=1;i<=row;i++)  
    {  
        cin>>pb_state;  
        for(j=0; j<col; j++)  
            if(pb_state[j]=='H') hang[i]+=1<<j;   
    }  

    he=1;  
    for(i=0;i<(1<<col);i++)  
    {  
        if((i&i<<1)||(i&i<<2)) continue;  
        state[he]=i;  
        int temp=i,num=0;  
        while(temp)  
        {  
            num += temp&1;  
            temp=temp>>1;  
        }  
        solider[he]=num;  
        he++;  
    }  
    for(i=1;i<he;i++)  
    {  
        if(state[i]&hang[1])continue;  
        dp[1][i][0]= solider[i];  
    }  
    for(i=1;i<he;i++)  
    {  
        if(state[i]&hang[2])continue;  
        for(j=1;j<he;j++)  
        {  
            if(state[i]&state[j])continue;  
            if(state[j]&hang[1]) continue;  
            dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+solider[i]);  
        }  
    }  
    for(h=3;h<=row;h++)  
    {  
        for(i=1;i<he;i++)// 
        {  
            if(state[i]&hang[h])continue;  
            for(j=1;j<he;j++)  
            {  
                if(state[j]&hang[h-1])continue;  
                if(state[j]&state[i])continue;  
                for(k=1;k<he;k++)  
                {  
                    if(state[k]&hang[h-2])continue;  
                    if(state[k]&state[i])continue;  
                    if(state[k]&state[j])continue;  

                    dp[h][i][j]=max(dp[h][i][j],dp[h-1][j][k]+solider[i]);  
                }  
            }  
        }  
    }  
    int ans=0;  
    for(i=1;i<he;i++)  
        for(j=0;j<he;j++)//!!!注意啊,这里一定是从0开始的,因为之前设置好的就是0啊。。。。。。。。。。。。。。。。。。 
            ans=max(ans,dp[row][i][j]);  
    cout<<ans<<endl;  
    //system("pause"); 
    return 0;  
}  

你可能感兴趣的:(dp,poj)