• UVa12235 Help Bubu


    难啊!

    分析题目,发现书高范围挺小的,估摸着是个状态压缩。

    然后就卡住了,再然后无比熟练的找到了题解

    先思考状态吧。首先前 i 个,选 j 个肯定是要有的。

    决策肯定是选和不选。

    不选的时候,messval的值肯定跟上一个结尾的高度有关,所以状态里肯定有结尾的高度。

    很明显,肯定要记录 拿走或者剩余哪些高度 以及 所有的高度。

    于是终于思考出状态 :

     int f[2][MAXN][MAXH][10];//前i个, 选j个, 书架上剩余书目集合, 最后一本书的高度 

    然后就可以码了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1e2 + 5;
    const int MAXH = (1 << 8) + 2;
    
    int f[2][MAXN][MAXH][10];//前i个, 选j个, 书架上剩余书目集合, 最后一本书的高度
    int N, K;
    
    int main()
    {
        int T = 0;
        while(cin>>N>>K, (N + K))
        {
            int d = 0, all = 0;
            memset(f[d], 0x3f, sizeof(f[d]));
            for(int i = 0; i < N; i++){
                int h; scanf("%d", &h);
                h -= 25;
                d ^= 1; memset(f[d], 0x3f, sizeof(f[d]));
                f[d][i][(1 << h)][h] = 1;
                for(int j = 0; j <= min(i, K); j++)
                    for(int s = all; s; s = (s - 1) & all)
                        for(int k = 0; k < 8; k++){
                            if(f[d ^ 1][j][s][k] == INF) continue;
                            if(h == k) f[d][j][s][h] = min(f[d][j][s][h], f[d ^ 1][j][s][k]);//不拿
                            else {
                                f[d][j][s | (1 << h)][h] = min(f[d][j][s | (1 << h)][h], f[d ^ 1][j][s][k] + 1);
                                f[d][j + 1][s][k] = min(f[d][j + 1][s][k], f[d ^ 1][j][s][k]);//
                            }
                        }
                all |= (1 << h);
            }
            int ans = INF;
            for(int j = 0; j <= K; j++)
                for(int s = all; s; s = (s - 1) & all)
                    for(int k = 0; k < 8; k++){
                        if(f[d][j][s][k] == INF) continue;
                        int cnt = 0;
                        for(int tmp = s ^ all; tmp; tmp >>= 1)
                            if(tmp & 1) ++cnt;
                        ans = min(ans, f[d][j][s][k] + cnt);
                    }
            printf("Case %d: %d
    
    ", ++T, ans);
        }
        return 0;
    }

     

  • 相关阅读:
    MD5加密 + 盐
    SQLite数据库--C#访问加密的SQLite数据库
    SQLite问题笔记
    微信开发--Two.菜单生成
    NOIP2018游记(更新完毕)
    HNOI2019 游记
    JXOI2017-2018 解题报告
    网络流20+4题解题报告(已更前20题)
    CodeForces528A (STLset)
    CodeForces 140C New Year Snowmen(堆)
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9285666.html
Copyright © 2020-2023  润新知