zoukankan      html  css  js  c++  java
  • UVa 12235 状压DP Help Bubu

    题解戳这

    一开始没看懂题解,后来想明白以后,d(i, j, s, x)是考虑第i本书的时候,前面已经拿走了j本书,剩下的书的种类的二进制状态为s,剩下的最后一本书的编号为x,所能得到的最小混乱度。

    这里状态定义的时候,先不考虑把拿出来的书放回去。

    最后统计答案的时候,把那些拿出来的书再加上。

    all是所有n本书的状态,s是剩下书的种类的状态。

    如果拿出来的书中有和前面高度相同的,直接插到相邻的位置就行了,不会增加混乱度。

    如果拿出来的书中没有和前面高度相同的,不管放在那里混乱度都会加1,这样所增加的混乱度就是bitcount(all ^ s)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int maxn = 100 + 5;
     7 const int maxs = (1 << 8);
     8 const int INF = 0x3f3f3f3f;
     9 
    10 int n, k;
    11 
    12 int a[maxn];
    13 int d[2][maxn][maxs][8];
    14 
    15 int bitcount(int x)
    16 {
    17     int ans = 0;
    18     while(x) { ans += (x&1); x >>= 1; }
    19     return ans;
    20 }
    21 
    22 int main()
    23 {
    24     int kase = 0;
    25 
    26     while(scanf("%d%d", &n, &k) == 2)
    27     {
    28         if(!n && !k) break;
    29 
    30         for(int i = 0; i < n; i++) scanf("%d", a + i);
    31 
    32         memset(d[0], 0x3f, sizeof(d[0]));
    33         int cur = 0;
    34         int all = 0;
    35 
    36         for(int i = 0; i < n; i++)
    37         {
    38             cur ^= 1;
    39             memset(d[cur], 0x3f, sizeof(d[cur]));
    40             int h = a[i] - 25;
    41             d[cur][i][1<<h][h] = 1;
    42 
    43             for(int j = 0; j <= min(k, i); j++)
    44                 for(int s = all; s; s = (s-1)&all)
    45                     for(int x = 0; (1 << x) <= s; x++)
    46                         if(d[cur^1][j][s][x] != INF)
    47                         {
    48                             int t = d[cur^1][j][s][x];
    49                             if(x == h) d[cur][j][s][x] = min(d[cur][j][s][x], t);
    50                             else
    51                             {
    52                                 d[cur][j+1][s][x] = min(d[cur][j+1][s][x], t);
    53                                 d[cur][j][s|(1<<h)][h] = min(d[cur][j][s|(1<<h)][h], t + 1);
    54                             }
    55                         }
    56             all |= (1 << h);
    57         }
    58 
    59         int ans = n;
    60         for(int j = 0; j <= k; j++)
    61             for(int s = all; s; s = (s-1)&all)
    62                 for(int x = 0; (1 << x) <= s; x++)
    63                     ans = min(ans, d[cur][j][s][x] + bitcount(all^s));
    64         printf("Case %d: %d
    
    ", ++kase, ans);
    65     }
    66 
    67     return 0;
    68 }
    代码君
  • 相关阅读:
    国旗国徽图案标准版本
    Microsoft Office 2013 64位免费完整版(office2013)
    PS的简单抠图教程
    1.5td什么意思
    html img 去除图片之间的缝隙
    PS如何去除图片上的网址
    如何用Photoshop/PS画直线
    实达690KPro参数
    Redis实战篇(一)搭建Redis实例
    Redis性能篇(五)Redis缓冲区
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4702669.html
Copyright © 2011-2022 走看看