[POJ 1185] [NOI 2001] 포병 진지 상 압 DP

제목 링크:http://poj.org/problem?id=1185
누 드 상 압 으로 한 줄 에 2 진법 으로 모든 상 태 를 저장 하 는 것 을 고려 하지만 상태 가 너무 많아 서 할 수 없다.
많은 상태 가 비합법적 인 것 을 관찰 했 기 때문에 우 리 는 합 법 적 인 상 태 를 미리 처 리 했 고 60 가지 만 발견 한 후에 마음대로 DP 를 하면 된다.
 
 1 #include
 2 #include
 3 #include
 4 using namespace std;
 5 int N,M;
 6 char G[110][15];
 7 int s[65],cnt[65],scnt=0,ban[65];
 8 int f[110][65][65];
 9 int main(){
10     memset(ban,0,sizeof(ban));
11     memset(f,0,sizeof(f));
12     memset(cnt,0,sizeof(cnt));
13     memset(s,0,sizeof(s));
14     scanf("%d%d",&N,&M);
15     for(int i=1;i<=N;i++) scanf("%s",G[i]);
16     for(int i=1;i<=N;i++)
17         for(int j=0;j)
18             if(G[i][j]=='H')
19                 ban[i]|=(1<<j);
20     int tmp=1<<M;
21     for(int i=0;i){
22         bool flag=true;
23         for(int j=0;j){
24             int tmp=((i&(1<0)+((i&(1<1))>0)+((i&(1<2))>0);
25             if(tmp>1){
26                 flag=false;
27                 break;
28             }
29         }
30         if(flag){
31             s[++scnt]=i;
32             for(int j=0;j)
33                 if(i&(1<<j))
34                     cnt[scnt]++;
35         }
36     }
37     for(int i=1;i<=scnt;i++)
38         if((s[i]&ban[1])==0)
39             f[1][1][i]=cnt[i];
40     for(int i=1;i<=scnt;i++)
41         if((s[i]&ban[2])==0)
42             for(int j=1;j<=scnt;j++)
43                 if((s[i]&s[j])==0&&(s[j]&ban[1])==0)
44                     f[2][j][i]=max(f[2][j][i],f[1][1][j]+cnt[i]);
45     for(int i=3;i<=N;i++)
46         for(int j=1;j<=scnt;j++)
47             if((s[j]&ban[i-2])==0)
48                 for(int k=1;k<=scnt;k++)
49                     if((s[j]&s[k])==0&&(s[k]&ban[i-1])==0)
50                         for(int t=1;t<=scnt;t++)
51                             if((s[j]&s[t])==0&&(s[k]&s[t])==0&&(s[t]&ban[i])==0)
52                                 f[i][k][t]=max(f[i][k][t],f[i-1][j][k]+cnt[t]);
53     int Ans=0;
54     for(int i=1;i<=scnt;i++)
55         for(int j=1;j<=scnt;j++)
56             Ans=max(Ans,f[N][i][j]);
57     printf("%d
",Ans); 58 return 0; 59 }

좋은 웹페이지 즐겨찾기