zoukankan      html  css  js  c++  java
  • Luogu 2157 [SDOI2009]学校食堂

    Solution

    比较好想的dp, 但是坑不少QAQ, 调半天

    由于容忍度 $b_i$<= 7, 所以可以考虑将第$i$个人接下来的$b_i$ 个人作为一个维度记录状态。

    于是我们定义数组$f[ i ][ S ]$ 表示前$i-1$个人都已经拿到了菜, S表示$i$和接下来$b_i$个人是否拿到了菜。

    然后依次枚举$i$ :第$i$个人, $S$ : $i$与接下来$b_i$个人是否拿到菜, $nt$ : 下一次谁拿菜, $fr$ : 上一次谁拿菜

    还需要通过$judge$来判断该状态是否可行, 最后进行$dp$

    具体看代码里的$jud$ 和$dp$ 函数

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 #define rep(i,a,b) for(register int i = (a); i <= (b); ++i)
     6 #define per(i,a,b) for(register int i = (a); i >= (b); --i)
     7 using namespace std;
     8 
     9 const int N = 1e3 + 100;
    10 const int base = 10;
    11 const int inf = 1061109567;
    12 
    13 int tas[N], bac[N], f[N][300][25];
    14 int n, T;
    15 
    16 int read() {
    17     int X = 0, p = 1; char c = getchar();
    18     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    19     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    20     return X * p;
    21 }
    22 
    23 int jud(int now, int S, int nt, int fr) {
    24     if(f[now][S][fr +base] >= inf) return 0;
    25     if((S >> nt) & 1) return 0;
    26     if(!((S >> fr) & 1) && fr >= 0) return 0;
    27     if(now + fr < 0) return 0;
    28     rep(i, now, now + nt) if(!((S >> (i - now)) & 1) && now + nt > i + bac[i]) return 0;
    29     return 1;
    30 }
    31 
    32 void dp(int now, int S, int nt, int fr) {
    33     int ntS = S | (1 << nt), tmp = inf; //ntS表示给nt拿完菜的状态
    34     if(now + fr) tmp = min(tmp, f[now][S][fr + base] + (tas[now + nt] ^ tas[now + fr]));
    35     else tmp = min(tmp, f[now][S][fr + base] + 0);
    36     nt += now;
    37     for(; ntS & 1; ntS >>=  1) {
    38         f[now][ntS][nt - now + base] = min(f[now][ntS][nt - now + base], tmp);
    39         //printf("%d %d %d
    ", now, ntS, nt);
    40         now++;
    41     }
    42     f[now][ntS][nt - now + base] = min(f[now][ntS][nt - now + base], tmp);
    43     //printf("%d %d %d
    ", now, ntS, nt);
    44 }
    45 
    46 void work() {
    47     memset(f, 63, sizeof(f));
    48     n = rd;
    49     rep(i, 1, n) tas[i] = rd, bac[i] = rd;
    50     f[1][0][-1 + base] = 0;
    51     rep(i, 1, n) rep(j, 0, (1 << (bac[i] + 1)) - 1) rep(k, 0, bac[i]) rep(fr, -8, 7) {//fr必须从-8枚举
    52         if(!jud(i, j, k, fr)) continue;
    53         dp(i, j, k, fr);
    54     }
    55     int ans = inf;
    56     rep(i, -7, 7) ans = min(ans, f[n][1][i + base]);
    57     printf("%d
    ", ans);
    58 }
    59 
    60 int main()
    61 {
    62     T = rd;
    63     rep(i, 1, T) work();
    64 }
    View Code
  • 相关阅读:
    axis2依赖的其他jar, 版本不是最新的
    mysql: 安装后的目录结构
    视图的使用
    索引
    递归查询 start with connect by prior
    oracle创建表
    C#中 ??、 ?、 ?: 、?.、?[ ] 和$
    C#关键字static、virtual和abstract笔记
    js调用后台,后台调用前台等方法总结
    java基础序列化
  • 原文地址:https://www.cnblogs.com/cychester/p/9590500.html
Copyright © 2011-2022 走看看