题目

传送们

小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭。学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴。当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示。 由于人手不够,食堂每次只能为一个人做菜。做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的。其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运算符为“|”和“&”。

学生数目相对于这个学校还是比较多的,吃饭做菜往往就会花去不少时间。因此,学校食堂偶尔会不按照大家的排队顺序做菜,以缩短总的进餐时间。

虽然同学们能够理解学校食堂的这种做法,不过每个同学还是有一定容忍度的。也就是说,队伍中的第i 个同学,最多允许紧跟他身后的Bi 个人先拿到饭菜。一旦在此之后的任意同学比当前同学先拿到饭,当前同学将会十分愤怒。因此,食堂做菜还得照顾到同学们的情绪。 现在,小F 想知道在满足所有人的容忍度这一前提下,自己的学校食堂做完这些菜最少需要多少时间。

输入格式

第一行包含一个正整数C,表示测试点的数据组数。 每组数据的第一行包含一个正整数N,表示同学数。 每组数据的第二行起共N行,每行包含两个用空格分隔的非负整数Ti和Bi,表示按队伍顺序从前往后的每个同学所需的菜的口味和这个同学的忍受度。 每组数据之间没有多余空行。

输出格式

包含C行,每行一个整数,表示对应数据中食堂完成所有菜所需的最少时间。

输入输出样例

输入

2
5
5 2
4 1
12 0
3 3
2 2
2
5 0
4 0

输出

16
1

思路

设dp[i][j][k]表示第1到第i-1个人已经打到饭,i以及后面7个人的状态为j,最后一个打饭的编号为i+k,(k的范围是-8到7),那么我们分析转移

  • 第i个人已经打完饭,那么i后面的7个人只能在i后面打饭(i:我打完了,你们随意),那么可以直接更新i+1的状态
dp[i+1][j>>1][k-1]=min(dp[i+1][j>>1][k-1],dp[i][j][k]);
  • i并没有打完饭,这时候并不是简单的枚举i后面的b[i]个人,而是向后找忍耐度+其位置的最小值,因为每个人的忍耐度是不一样的,就比如i的忍耐读是5,而i+1是1,那么只能是i后面两个人可以在i前面打饭,所以要考虑忍耐距离,枚举i后面7个人,在满足该条件下可以进行转移,
dp[i][j|(1<<h)][h+8]=min(dp[i][j|(1<<h)][h+8],dp[i][j][k+8]+(i+k?(t[i+k]^t[i+h]):0));
  • 一点细节,k的范围是-8到7,所以存的时候要都加一下8,保证数组不越界(段错误警告)。
  • (Ai​ or Ai+1​)−(Ai​ and Ai+1​) = Ai​ xor Ai+1​

附上代码

#include<bits/stdc++.h>
using namespace std;
int T;
const int maxn=1000+10;
const int N=1<<8;
const int inf=0x7f7f7f7f;
int dp[maxn][N][20];
int t[maxn],b[maxn],n; inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
} int main(){
T=read();
while(T--){
memset(t,0,sizeof(t));//记得初始化
memset(b,0,sizeof(b));
n=read();
for(int i=1;i<=n;i++){
t[i]=read();
b[i]=read();
}
memset(dp,0x7f,sizeof(dp));//初始化无穷大
dp[1][0][7]=0;//第0个人已经打完,上一个打饭的人是7-8(不存在)
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<8);j++){
for(int k=-8;k<=7;k++){
if(dp[i][j][k+8]!=inf){//除去效操作
if(j&1)dp[i+1][j>>1][k+7]=min(dp[i+1][j>>1][k+7],dp[i][j][k+8]);
else{
int lim=inf;//设定边界
for(int h=0;h<=7;h++){
if(!((j>>h)&1)){
if(i+h>lim)break;超过最大边界,不能转移
lim=min(lim,i+h+b[i+h]);
dp[i][j|(1<<h)][h+8]=min(dp[i][j|(1<<h)][h+8],dp[i][j][k+8]+(i+k?(t[i+k]^t[i+h]):0));//i+k==0,无需等待
}
} }
}
}
}
}
int ans=inf;
for(int k=0;k<=8;k++){
ans=min(ans,dp[n+1][0][k]);
}
cout<<ans<<endl; } }

状压DP之学校食堂的更多相关文章

  1. bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)

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

  2. BZOJ 1226 学校食堂(状压DP)

    状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...

  3. [luoguP2157] [SDOI2009]学校食堂Dining(状压DP)

    传送门 这种鬼畜的状压DP...第一次见 看到 0 <= Bi <= 7 就应该想到状态压缩,然而此题实在太鬼畜,想到也没什么乱用 f[i][j][k]表示前i-1个人全部吃完,i~i+7 ...

  4. [学习笔记]状压dp

    状压 \(dp\) 1.[SDOI2009]Bill的挑战 \(f[i][j]\) 表示匹配到字符串的第 \(i\) 位状态为 \(j\) 的方案数 那么方程就很明显了,每次枚举第 \(i\) 位的字 ...

  5. 状压DP之LGTB 与序列

    题目 思路 这道题竟然是状压DP,本人以为是数论,看都没看就去打下一题的暴力了,哭 \(A_i\)<=30,所以我们只需要考虑1-58个数,再往后选的话还不如选1更优,注意,1是可以重复选取的, ...

  6. [欢乐赛]班服 状压DP

    班服 (shirt.pas/.c/.cpp) 时间限制:1s:内存限制 128MB 题目描述: 要开运动会了,神犇学校的n个班级要选班服,班服共有100种样式,编号1~100.现在每个班都挑出了一些样 ...

  7. 【vijos】1286 座位安排(状压dp)

    https://vijos.org/p/1286 这题好神不会捉... 首先我们知道所有情况有C(n*m, k)种,这个好搞.但是两两不相邻这个有点难搞.. 原来是状压dp..sigh. 设状态f[i ...

  8. [luoguP3694] 邦邦的大合唱站队/签到题(状压DP)

    传送门 来自kkk的题解: 70分做法:枚举每个学校顺序,暴力. 100分:状压dp.从队列头到尾DP, 状态:f[i]表示i状态下最小的出列(不一致)的个数. 比如f[1101]表示从头到位为1/3 ...

  9. 状压DP UVA 10817 Headmaster's Headache

    题目传送门 /* 题意:学校有在任的老师和应聘的老师,选择一些应聘老师,使得每门科目至少两个老师教,问最少花费多少 状压DP:一看到数据那么小,肯定是状压了.这个状态不好想,dp[s1][s2]表示s ...

随机推荐

  1. Java实现第八届蓝桥杯承压计算

    承压计算 题目描述 X星球的高科技实验室中整齐地堆放着某批珍贵金属原料. 每块金属原料的外形.尺寸完全一致,但重量不同. 金属材料被严格地堆放成金字塔形. 7 5 8 7 8 8 9 2 7 2 8 ...

  2. cuda 9.0

    https://docs.nvidia.com/cuda/archive/9.0/index.html cuda9.0工具包

  3. python自学Day04(自学书籍python编程从入门到实践)

    第5章 if 语句 5.1 一个简单的示例 使用前面的解析列表构建一个0-9的数值列表. 判断0是否在列表中,如果在输出 0在列表A中 A = [i for i in range(0,10)] if ...

  4. mysql基础-数据库初始化操作必要步骤和客户端工具使用-记录(二)

    0x01 mysql启动时,读取配置文件的顺序 Default options are read from the following files in the given order:/etc/my ...

  5. 【大厂面试06期】谈一谈你对Redis持久化的理解?

    Redis持久化是面试中经常会问到的问题,这里主要通过对以下几个问题进行分析,帮助大家了解Redis持久化的实现原理. 1.Redis持久化是什么? 2.Redis持久化有哪些策略?各自的实现原理是怎 ...

  6. PyQt5中QTableView函数讲解

    如果想熟悉QTableWidget,请参考PyQt5高级界面控件之QTableWidget(四) setSpan(int, int, int, int)四个参数分别代表,起始行,列,合并的行数,全并的 ...

  7. [FireDAC][Phys][MSSQL]-310._数据库安装工具_问题需要解决_连载_3

    //先来看看我们碰到的问题,再来求解答SQL脚本执行失败,[FireDAC][Phys][MSSQL]-310. Cannot execute command returning result set ...

  8. 从零开始的Spring Boot(2、在Spring Boot中整合Servlet、Filter、Listener的方式)

    在Spring Boot中整合Servlet.Filter.Listener的方式 写在前面 从零开始的Spring Boot(1.搭建一个Spring Boot项目Hello World):http ...

  9. jmeter组件中 测试计划,线程组,sampler等等

    [测试计划] 这边用户定义的变量,定义整个测试中使用的重复值(全局变量),一般定义服务器的ip,端口号 [线程组] 关于,线程组,我简单聊聊,有不对的地方欢迎大家拨乱反正 线程数:你需要运行的线程 比 ...

  10. 查找nginx安装目录并启动

    今天公司突然停电,来电后发现服务无法访问了,服务器是部署在公司内 发现ip ping 不通,是服务器没开 手动开了服务器,还是无法访问 可以FTP,但是不能访问服务,说明机器已经开了,有些东西应该没启 ...