题目地址:Ural 1152
初学状压DP,原来状压仅仅是用到了个位运算。。
非常水的状压DP。注意四则运算的优先级是高于位运算的。。也就是说假设既用到了四则运算。也用到了位运算。要想先算位运算的话,要将位运算加括号。由于这个地方调了好久。。
代码例如以下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; int dp[1<<21]; int sum[1<<21]; int a[30]; int main() { int n, i, j, y1, y2, x; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); } memset(sum,0,sizeof(sum)); memset(dp,INF,sizeof(dp)); for(i=1;i<=(1<<n)-1;i++) { for(j=1;j<=n;j++) { if(i&(1<<j-1)) sum[i]+=a[j]; } //printf("%d ",sum[i]); } //puts(""); dp[(1<<n)-1]=0; for(i=(1<<n)-1;i>=1;i--) { for(j=0;j<n;j++) { if(i&(1<<j)) { x=i-(1<<j); //printf("1--%d %d %d ",i,1<<j, x); if(j==0) y1=n-1; else y1=j-1; if(j==n-1) y2=0; else y2=j+1; if(i&(1<<y1)) x-=1<<y1; //printf("2--%d ",x); if(i&(1<<y2)) x-=1<<y2; //printf("3--%d ",x); dp[x]=min(dp[x],dp[i]+sum[x]); } } } /*for(i=0;i<1<<n;i++) { printf("%d ",dp[i]); } puts("");*/ printf("%d ",dp[0]); return 0; }