• 【简●解】学校食堂


    【大意】

    懒癌晚期,直接丢传送门,,,

    【分析】

    开始拿到这道题没有太多的思路,再看了看数据范围,(B_ile 7)??应该是状压吧,,,然后开始往状压上想。还真是呢。。。

    开始推了个错误的方程导致一直(WA),后来瞟了眼题解,才发现自己方程的状态没有表示完,,,

    我们设(f[i][j][k])表示前(i-1)个人已经打完了饭,第(i)个人以及后面(7)个人打饭的状态为(j),最后一个打饭的人的编号为(i+k),容易知道(k)的范围为(-8le kle 7),那么转移就比较明显了。

    先考虑(j&1),即第(i)个人打好饭时,那么就可以直接转移到(f[i+1][j>>1][k-1])

    再思考其他情况,它们只能在(f[i][...][...])以内转移。

    因为(1)~(i-1)已经打完饭,所以考虑枚举打(i+h(0le hle 7))的饭,如果符合情况就转移到(f[i][j|(1 << h)][h])

    又因为(k)可以取到负数,所以就把第三维加个偏移量,就行了。

    【Code】

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int BASE = 8;
    const int MAX = 1000 + 5;
    const int INF = 0x3f3f3f3f;
    inline int read(){
        bool f = 0;int x = 0;char ch;
        do { ch = getchar(); if (ch == '-') f = 1; } while (ch < '0' || ch > '9');
        do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); 
        return f ? ~x + 1 : x;
    }
    inline int min(int a, int b) { return a < b ? a : b; }
    int C, n, t[MAX], b[MAX], f[MAX][1 << 8][20], rate, ans;
    int main(){
        C = read();
        while (C--) {
            n = read();
            ans = INF;
            for (int i = 1;i <= n; ++i) {
                t[i] = read(), b[i] = read();
            }
            memset(f, 0x3f, sizeof f);
            f[1][0][BASE - 1] = 0;
            for (int i = 1;i <= n; ++i) {
                for (int j = 0;j < (1 << 8); ++j) {
                    for (int k = -8;k <= 7; ++k) {
                        if (f[i][j][k + BASE] != INF) {
                            if (j & 1) {
                                f[i + 1][j >> 1][k - 1 + BASE] = min(f[i + 1][j >> 1][k - 1 + BASE], f[i][j][k + BASE]);
                            }
                            else {
                                rate = INF;
                                for (int h = 0;h <= 7; ++h) if (!((j >> h) & 1)){
                                    if (i + h > rate) break;
                                    rate = min(rate, i + h + b[i + h]);
                                    f[i][j | (1 << h)][h + BASE] = min(f[i][j | (1 << h)][h + BASE], f[i][j][k + BASE] + ((i + k) ? (t[i + k] | t[i + h]) - (t[i + k] & t[i + h]) : 0));
                                }
                            }
                        }
                    }
                }
            }
            for (int k = 0;k <= 8; ++k) ans = min(f[n + 1][0][k], ans);
            printf("%d
    ", ans); 
        }
        return 0;
    }
    
  • 相关阅读:
    Solution -「LOCAL」客星璀璨之夜
    Solution -「LOCAL」割海成路之日
    aaa
    wendang
    OSS架构
    MySQL事务
    1292分数和
    printf使用方法 (c++)
    1024与圆相关的计算
    Js 之echarts世界地图与汉化
  • 原文地址:https://www.cnblogs.com/silentEAG/p/11453276.html
Copyright © 2020-2023  润新知