zoukankan      html  css  js  c++  java
  • hdu 2167 Pebbles(状态压缩DP)

    入门级状态压缩dp题。

    题意:从方格中取一些数,要求所取位置不相邻(包括对角线相邻),求最大的和。

    做法:把每行的状态压缩成二进制数,设状态dp[i][p]为第i行取集合p,容易得出dp[i][p] = max{dp[i-1][q] + cnt[i][p]| 集合p,q可以共存},cnt[i][p]为第i行为集合p时所取得数的和。

    View Code
      1 /*
      2  *Author:       Zhaofa Fang
      3  *Created time: 2013-03-31-10.33
      4  *Language:     C++
      5  */
      6 #include <cstdio>
      7 #include <cstdlib>
      8 #include <sstream>
      9 #include <iostream>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <string>
     14 #include <utility>
     15 #include <vector>
     16 #include <queue>
     17 #include <stack>
     18 #include <map>
     19 #include <set>
     20 using namespace std;
     21 
     22 typedef long long ll;
     23 #define DEBUG(x) cout<< #x << ':' << x << endl
     24 #define REP(i,n) for(int i=0;i < (n);i++)
     25 #define REPD(i,n) for(int i=(n-1);i >= 0;i--)
     26 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
     27 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
     28 #define PII pair<int,int>
     29 #define PB push_back
     30 #define MP make_pair
     31 #define ft first
     32 #define sd second
     33 #define lowbit(x) (x&(-x))
     34 #define INF (1<<30)
     35 
     36 int k;
     37 int maz[17][17],dp[2][1600];
     38 int cnt[20][1600];
     39 int s[1600];
     40 bool ok(int x){
     41     if(x&(x<<1))return false;
     42     return true;
     43 }
     44 int fun(int x,int row,int n){
     45     int res=0,j=0;
     46     REP(j,n){
     47         if(x&(1<<j))res+=maz[row][j];
     48     }
     49     return res;
     50 }
     51 void pre_deal(int n){
     52 
     53     memset(s,0,sizeof(s));
     54     memset(cnt,0,sizeof(cnt));
     55     REP(i,(1<<n)){
     56         if(ok(i)){
     57             s[k++] = i;
     58         }
     59     }
     60     REP(i,n){
     61         REP(j,k)
     62         cnt[i][j] = fun(s[j],i,n);
     63     }
     64 }
     65 
     66 int main(){
     67     //freopen("in","r",stdin);
     68     //freopen("out","w",stdout);
     69     char str[100];
     70     while(gets(str)){
     71         int len = strlen(str);
     72         int n=0,res=0;
     73         REP(i,len){
     74             if(str[i]>='0'&&str[i]<='9')res = res*10+str[i]-'0';
     75             else {
     76                 maz[0][n++] = res;
     77                 res = 0;
     78             }
     79         }
     80         maz[0][n++]=res;
     81         FOR(i,1,n-1)REP(j,n)scanf("%d",&maz[i][j]);
     82         getchar();
     83         gets(str);
     84         k = 0;
     85         pre_deal(n);
     86         memset(dp,-1,sizeof(dp));
     87         int now = 1;
     88         REP(i,k)dp[now][i] = cnt[0][i];
     89         FOR(i,1,n-1){
     90             now ^= 1;
     91             REP(p,k){
     92                 REP(q,k){
     93                     if(s[p]&s[q])continue;
     94                     if(s[p]&(s[q]<<1))continue;
     95                     if(s[p]&(s[q]>>1))continue;
     96                     if(dp[now^1][q]==-1)continue;
     97                     dp[now][p] = max(dp[now][p],dp[now^1][q]+cnt[i][p]);
     98                 }
     99             }
    100         }
    101         int ans = 0;
    102         REP(i,k)ans=max(ans,dp[now][i]);
    103         printf("%d\n",ans);
    104     }
    105     return 0;
    106 }
    by Farmer
  • 相关阅读:
    (模板)高斯消元法模板
    poj1797(dijstra变形,求最小边的最大值)
    poj2253(floyd变形)
    (模板)poj2387(dijkstra+优先队列优化模板题)
    poj1915(双向bfs)
    poj3977(折半枚举+二分查找)
    uva11624 Fire! (bfs预处理)
    codeforces#1152C. Neko does Maths(最小公倍数)
    codeforces#1154F. Shovels Shop (dp)
    codeforces#1136E. Nastya Hasn't Written a Legend(二分+线段树)
  • 原文地址:https://www.cnblogs.com/fzf123/p/2991557.html
Copyright © 2011-2022 走看看