[状压dp]HDOJ1565 方格取数(1)
中文题~~ 题意略
$n\le 20$ ! 很明显是状压!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <climits> 5 #include <cctype> 6 #include <cmath> 7 #include <string> 8 #include <sstream> 9 #include <iostream> 10 #include <algorithm> 11 #include <iomanip> 12 using namespace std; 13 #include <queue> 14 #include <stack> 15 #include <vector> 16 #include <deque> 17 #include <set> 18 #include <map> 19 typedef long long LL; 20 typedef long double LD; 21 #define pi acos(-1.0) 22 #define lson l, m, rt<<1 23 #define rson m+1, r, rt<<1|1 24 typedef pair<int, int> PI; 25 typedef pair<int, PI> PP; 26 #ifdef _WIN32 27 #define LLD "%I64d" 28 #else 29 #define LLD "%lld" 30 #endif 31 //#pragma comment(linker, "/STACK:1024000000,1024000000") 32 //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;} 33 //inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;} 34 //inline void print(LL x){printf(LLD, x);puts("");} 35 //inline void read(double &x){char c = getchar();while(c < '0') c = getchar();x = c - '0'; c = getchar();while(c >= '0'){x = x * 10 + (c - '0'); c = getchar();}} 36 37 int mp[25][25]; 38 int dp[2][1<<20]; // n格为一个状态 39 int p[1<<20], d; 40 void pre() //先记录所有的合法状态 即不相邻 41 { 42 d=0; 43 for(int i=0;i<(1<<20);i++) 44 if((i & (i<<1))==0) 45 p[d++]=i; 46 } 47 int main() 48 { 49 #ifndef ONLINE_JUDGE 50 freopen("in.txt", "r", stdin); 51 freopen("out.txt", "w", stdout); 52 #endif 53 pre(); 54 int n; 55 while(~scanf("%d", &n)) 56 { 57 for(int i=0;i<n;i++) 58 for(int j=0;j<n;j++) 59 scanf("%d", &mp[i][j]); 60 memset(dp, 0, sizeof(dp)); 61 int cur=0; 62 for(int i=0;i<n;i++) 63 { 64 for(int k=0;k<d;k++) 65 { 66 int sum=0; 67 if(p[k]>=(1<<n)) // 算是优化吧 没有就tle了 68 break; 69 for(int j=0;j<n;j++) 70 if(p[k] & (1<<j)) 71 sum+=mp[i][j]; 72 for(int j=0;j<d;j++) 73 { 74 if(p[j]>=(1<<n)) // 算是优化吧 没有就tle了 75 break; 76 if((p[k] & p[j])==0) 77 dp[cur][p[k]]=max(dp[cur][p[k]], dp[cur^1][p[j]]+sum); 78 } 79 } 80 cur^=1; 81 } 82 cur^=1; 83 int ans=0; 84 for(int i=0;i<(1<<n);i++) 85 ans=max(ans, dp[cur][i]); 86 printf("%d\n", ans); 87 } 88 return 0; 89 }