BZOJ原题链接

洛谷原题链接

注意到\(B[i]\)很小,考虑状压\(DP\)。

设\(f[i][j][k]\)表示前\(i - 1\)个人已经拿到菜,第\(i\)个人及其后面\(7\)个人是否拿到菜的状态为\(j\),上一个拿到菜的人的编号为\(i + k,-8\leqslant k \leqslant 7\)时所用的最短时间。

然后讨论状态的转移。

  • \(j \& 1\)为真

    说明第\(i\)个人已经拿到菜,可以直接转移至\(i + 1\),即$$f[i + 1][j >> 1][k - 1] = \min{ f[i + 1][j >> 1][k - 1], f[i][j][k] }$$
  • \(j \& 1\)为假

    此时不能转移至\(i + 1\),因为第\(i\)个人还没拿到菜,不满足定义。

    于是我们可以枚举\(q = 0 \to 7\),选出\(i\)后的第\(q\)个人去拿饭:$$f[i][j | (1 << h)][h] = \min{ f[i][j | (1 << h)][h], f[i][j][k] + time(i + k, i + h) }$$

    \(time(x,y)\)表示上一个拿菜的人的编号为\(x\),这次为\(y\),则需要做菜的时间。

    而在转移这种状态时,需要考虑每个人的容忍度,在循环\(q\)的过程中,维护一个最小的容忍度,若枚举到的人已经不被之前未拿菜的某人所容忍,那么就不需要考虑这个人与其之后的人了。

最后答案为:\(\min \limits ^ {-8\leqslant k \leqslant 0} \{ f[n + 1][0][k] \}\)。

因为\(k\)可以为负,所以在储存是要整体右移。

另外,题目中给出计算时间的公式\((a | b) - (a \& b)\),实际上等于\(a \land b\)。

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1010;
const int M = (1 << 8) + 10;
int f[N][M][20], T[N], B[N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void ckminn(int &x, int y)
{
if (x > y)
x = y;
}
int main()
{
int i, j, k, n, m = M - 10, t, q, edr, mi;
t = re();
while (t--)
{
n = re();
for (i = 1; i <= n; i++)
{
T[i] = re();
B[i] = re();
}
memset(f, 60, sizeof(f));
f[1][0][7] = 0;
for (i = 1; i <= n; i++)
for (j = 0; j < m; j++)
for (k = -8 ; k <= 7; k++)
if (f[i][j][k + 8] < 1e8)
{
if (j & 1)
ckminn(f[i + 1][j >> 1][k + 7], f[i][j][k + 8]);
else
{
edr = 1e9;
for (q = 0; q <= 7; q++)
if (!(j & (1 << q)))
{
if (i + q > edr)
break;
ckminn(edr, i + q + B[i + q]);
ckminn(f[i][j | (1 << q)][q + 8], f[i][j][k + 8] + (i + k ? T[i + k] ^ T[i + q] : 0));
}
}
}
for (mi = 1e9, i = 0; i <= 8; i++)
ckminn(mi, f[n + 1][0][i]);
printf("%d\n", mi);
}
return 0;
}

BZOJ1226或洛谷2157 [SDOI2009]学校食堂的更多相关文章

  1. 洛谷 P2157 [SDOI2009]学校食堂

    题意简述 每个人有一个口味,食堂每次只能为一个人做菜 做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为a 异或 b 每个人都有一个容忍度,最多允许紧 ...

  2. 洛谷 P2051 [SDOI2009]学校食堂

    传送门- 题目分析:首先,我们先看看做菜时间的运算机制.$(A~\texttt{or}~B)-(A~\texttt{and}~B)$这个试子看起来有点复杂(因为我太菜了),仔细想想,是不是可以转化为$ ...

  3. Luogu 2157 [SDOI2009]学校食堂 - 状压dp

    Solution 比较好想的dp, 但是坑不少QAQ, 调半天 由于容忍度 $b_i$<= 7, 所以可以考虑将第$i$个人接下来的$b_i$ 个人作为一个维度记录状态. 于是我们定义数组$f[ ...

  4. 【BZOJ1226】[SDOI2009]学校食堂Dining 状压DP

    [BZOJ1226][SDOI2009]学校食堂Dining Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满 ...

  5. BZOJ 1226: [SDOI2009]学校食堂Dining

    1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 730  Solved: 446[Submit][ ...

  6. 【题解】Luogu P2157 [SDOI2009]学校食堂

    原题传送门:P2157 [SDOI2009]学校食堂 一看题目就知道是状压dp 设f[i][j][k]表示第1到i-1个人都吃完了饭,第i个人以及后面的7个人是否打饭的状态为j,当前最后打饭的人的编号 ...

  7. 【bzoj1226】【[SDOI2009]学校食堂Dining】状压dp

    (上不了p站我要死了,侵权度娘背锅) Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人 ...

  8. BZOJ1226 [SDOI2009]学校食堂Dining 【状压dp】

    题目 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示 ...

  9. 【BZOJ1226】[SDOI2009] 学校食堂

    题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...

随机推荐

  1. linux 内核启动流程

    Linux内核启动流程详细分析: http://www.linuxidc.com/Linux/2014-10/108034.htm ARM Linux内核启动过程: http://blog.csdn. ...

  2. 1.5.6、CDH 搭建Hadoop在安装之前(定制安装解决方案---使用Cloudera Manager模板创建CDH群集)

    使用Cloudera Manager模板创建CDH群集 您可以通过从Cloudera Manager管理的现有CDH群集导出群集模板来创建新的CDH群集.然后,您可以修改模板并使用它在新的主机集上创建 ...

  3. mysql数据库备份shell

    sip=xxx.xxx.xxx.xxx user=user passwd=passwd back_path=/home/xxxxx/mysqlbak data_name=data_name date= ...

  4. python-ceilometerclient命令行(2)

    命令行解析工具argparse argparse是python标准库中的模块,利用argparse,可以完成对命令行的参数定义.解析以及后续的处理.一个简单的例子: # coding:utf-8 im ...

  5. linus上运行jar包文件增删查

    package com.osplat.util; import com.alibaba.fastjson.JSON; import com.osplat.bean.Resultmodel; impor ...

  6. python全栈开发 随笔 'is' 和 == 的比较知识与区别 编码和解码的内容及转换

    python 一. is 和 == 的区别; == 比较的是两边的值. a = 'alex' b = 'alex' print(a = b) #True a = 10 b = 10 print(a = ...

  7. 【OpenGL】纹理(Texture)

    纹理是一个2D图片(也有1D和3D),它用来添加物体的细节:这就像有一张绘有砖块的图片贴到你的3D的房子上,你的房子看起来就有了一个砖墙.因为我们可以在一张图片上插入足够多的细节,这样物体就会拥有很多 ...

  8. 网站访问者UA检测及跳转

    /*!* UA检测及跳转*/;(function(){ var whatdevice = {}; var myUA = window.navigator.userAgent.toLowerCase() ...

  9. POJ-1458.CommonSubsequence.(DP:最长公共子序列裸题)

    本题大意:给出两个字符串,让你求出最长公共子序列的长度并输出. 本题思路:本题是经典的DP问题,由于是两个字符串,那么我们就用一个二维数组来进行区分,用dp[ i ][ j ]来表示在s1和s2中分别 ...

  10. ASP.Net MVC 在ajax接收controller返回值为Json数据

    首先,再次回忆一下ajax的标准用法:(这张图写的比较详细了)(转) 页面部分ajax代码: $.ajax({            url: "/Home/Login?account=&q ...