POJ 1185 炮兵阵地 状压DP
http://poj.org/problem?id=1185
中文题目,开始觉得跟上个题目,种玉米那个一样的,只是这个是第三行受前两行的影响,,,后来发现不是。种玉米是最后有多少组合,这个是最多放多少部队,稍稍一变就行了
总体来说,这个题不是很难,还可以,就是我写的很纠结 MLE,TLE 用滚动数组解决了MLE,二进制预处理解决TLE 最后还是跑了1400+MS
代码:
//开始还MLE,dp[103][MAX+5][MAX+5]确实是超,后来用了滚动数组改成了TLE,最后预处理还跑了1400+MS #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<vector> #define MAX (1<<10) using namespace std; int dp[2][MAX+5][MAX+5]; vector<int>num[103]; int i,j,k; int r,c; int max(int a,int b) { return a>b?a:b; } void Get_state(int row,int temp) { num[i].clear(); for(int x=0;x<(1<<c);x++) { if(x&(x<<1) || x&(x<<2) || x&(x>>1) || x&(x>>2)) continue; if(temp&x) continue; num[i].push_back(x); } } void Judge() { int t1,t2,t3; int cnt; for(t1=0;t1<num[i-2].size();t1++) for(t2=0;t2<num[i-1].size();t2++) for(t3=0;t3<num[i].size();t3++) { if((num[i][t3]&num[i-2][t1])||(num[i][t3]&num[i-1][t2])) continue; cnt=0; int h=num[i][t3]; while(h) { if(h%2) cnt++; h/=2; } dp[i%2][t2][t3]=max(dp[i%2][t2][t3],dp[(i-1)%2][t1][t2]+cnt); } } int main() { char s[20]; int temp; while(~scanf("%d%d",&r,&c)) { num[0].clear(); num[0].push_back(0); num[1].clear(); num[1].push_back(0); for(i=2;i<=r+1;i++) { scanf("%s",s); temp=0; for(j=0;j<c;j++) { if(s[j]=='H') temp+=(1<<j); } Get_state(i,temp); } memset(dp,0,sizeof(dp)); for(i=2;i<=r+1;i++) { for(int h1=0;h1<num[i-1].size();h1++) for(int h2=0;h2<num[i].size();h2++) dp[i%2][h1][h2]=0; Judge(); } int ans=0; for(i=0;i<num[r].size();i++) for(j=0;j<num[r+1].size();j++) { ans=max(ans,dp[(r+1)%2][i][j]); } printf("%d\n",ans); } return 0; }