bzoj 1226 学校食堂Dining
Written with StackEdit.
Description
小\(F\) 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭。学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴。当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示。由于人手不够,食堂每次只能为一个人做菜。做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是\(a\),这一道为\(b\),则做这道菜所需的时间为\((a|b)-(a \&b)\),而做第一道菜是不需要计算时间的。学生数目相对于这个学校还是比较多的,吃饭做菜往往就会花去不少时间。因此,学校食堂偶尔会不按照大家的排队顺序做菜,以缩短总的进餐时间。虽然同学们能够理解学校食堂的这种做法,不过每个同学还是有一定容忍度的。也就是说,队伍中的第\(i\) 个同学,最多允许紧跟他身后的\(B_i\) 个人先拿到饭菜。一旦在此之后的任意同学比当前同学先拿到饭,当前同学将会十分愤怒。因此,食堂做菜还得照顾到同学们的情绪。现在,小\(F\) 想知道在满足所有人的容忍度这一前提下,自己的学校食堂做完这些菜最少需要多少时间。
Input
第一行包含一个正整数\(C\),表示测试点的数据组数。每组数据的第一行包含一个正整数\(N\),表示同学数。每组数据的第二行起共\(N\)行,每行包含两个用空格分隔的非负整数\(T_i\)和\(B_i\),表示按队伍顺序从前往后的每个同学所需的菜的口味和这个同学的忍受度。每组数据之间没有多余空行。
Output
包含\(C\)行,每行一个整数,表示对应数据中食堂完成所有菜所需的最少时间。
Sample Input
2
5
5 2
4 1
12 0
3 3
2 2
2
5 0
4 0
Sample Output
16
1
HINT
对于第一组数据:同学1允许同学2或同学3在他之前拿到菜;同学2允许同学3在他之前拿到菜;同学3比较小气,他必须比他后面的同学先拿菜…… 一种最优的方案是按同学3、同学2、同学1、同学4、同学5做菜,每道菜所需的时间分别是0、8、1、6及1。
[数据规模和约定]
对于\(30\%\)的数据,满足\(1 ≤ N ≤ 20\)。
对于\(100\%\)的数据,满足\(1 ≤ N ≤ 1,000,0 ≤ T_i ≤ 1,000,0 ≤ B_i ≤ 7,1 ≤ C ≤ 5\)。
存在\(30\%\)的数据,满足\(0 ≤ B_i ≤ 1\)。
存在\(65\%\)的数据,满足\(0 ≤ B_i ≤ 5\)。
存在\(45\%\)的数据,满足\(0 ≤ T_i ≤ 130\)。
Solution
- \(n\)较小,考虑状压\(dp\).
- 令\(f(i,j,k)\)表示前\(i-1\)个人吃了饭,\(i\)及\(i\)之后的属于集合\(j\)的人也吃了饭,最后一个吃饭的人为\(i+k\)时所用的花费.
- 转移时,如果\(j\&1=1\),说明\(i\)已经吃了饭.直接转移到\(f(i+1,j>>1,k)\),不需要额外花费.
- 否则,枚举下一个吃饭的人是\(i+l\),满足\(i+l\)还没有吃过饭.
- 这样就只能在\(l\geq0\)内找,因为状态定义满足\(i\)之前的都吃过饭.
- 还要满足\(l\notin j\),以及满足\([i,i+l-1]\)内的容忍度限制,即可完成转移.
- 答案为前\(n\)个人均吃了饭,且后面没有人再吃饭的最小花费,即\(min\{f(n+1,0,k)\}\).
- 注意到\(k\)可能为负数.所以需要将\(k\)平移为\(k+8\).
\((a|b)-(a \&b)=(a\)^\(b)\).
#include<bits/stdc++.h>
#define f(i,j,k) F[i][j][k+8]
#define inf 0x3f3f3f3f
#define st f(i,j,k)
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int MAXN=1e3+10;
int n,ans;
int t[MAXN],b[MAXN];
int F[MAXN][257][17];
inline int calc(int x,int y)//上一个恰饭的人是x,当前恰饭的人是y.计算花费.
{
return x==0? 0:t[x]^t[y];
}
// a|b - a&b = a^b
int main()
{
int T=read();
while(T--)
{
memset(F,inf,sizeof F);
n=read();
for(int i=1; i<=n; ++i)
t[i]=read(),b[i]=read();
f(1,0,-1)=0;
int S=1<<8;
for(int i=1; i<=n; ++i)
for(int j=0; j<S; ++j)
for(int k=-8; k<=7; ++k)
if(st<inf)
{
#define st1 f(i+1,j>>1,k-1)
#define st2 f(i,j+(1<<l),l)
if(j&1)
st1=min(st1,st);
else
{
int lim=inf;
for(int l=0; l<=7; ++l)
if(!(j&(1<<l)))//注意括号
{
if(i+l>lim)
break;
lim=min(lim,i+l+b[i+l]);
st2=min(st2,st+calc(i+k,i+l));
}
}
}
ans=inf;
for(int k=-8; k<=7; ++k)
ans=min(ans,f(n+1,0,k));
printf("%d\n",ans);
}
return 0;
}
bzoj 1226 学校食堂Dining的更多相关文章
- [SDOI2009][BZOJ 1226]学校食堂
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- bzoj [SDOI2009]学校食堂Dining
感觉这个状压dp比较难想.. dp[ i ][ s ][ k ] 表示前i - 1个都排好了, 从i开始的7个的取没取的状态为s, 且最后一个相对i的位置为k的最少花费. 状态转移方程 if(s &a ...
- BZOJ 1226 学校食堂(状压DP)
状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...
- BZOJ 1226: [SDOI2009]学校食堂Dining
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 730 Solved: 446[Submit][ ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
- 【BZOJ1226】[SDOI2009]学校食堂Dining 状压DP
[BZOJ1226][SDOI2009]学校食堂Dining Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满 ...
- 1226: [SDOI2009]学校食堂Dining - BZOJ
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- [SDOI2009]学校食堂Dining
题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
随机推荐
- iOS应用内付费(IAP)开发步骤
1.苹果iTunes Connect内购产品信息录入. 1)创建app内购买项目(Create New),选择类型: 1.消耗型项目 对于消耗型 App 内购买项目,用户每次下载时都必须进行购买.一次 ...
- hadoop09----线程池
java并发包 1.java并发包介绍 线程不能无限制的new下去,否则系统处理不了的. 使用线程池.任务来了就开一runable对象. concurrent 包开始不是jdk里面的,后来加入到jd ...
- 3d旋转动画焦点图
在线演示 本地下载
- 判断一个对象是否有new
C++语言中,对象没有空和不空的概念,只有对象指针才有空和不空的概念 判断对象指针是否为空只需要和NULL常量进行比较即可 如果相等,则为空,否则不为空 另外对象虽然没有空和不空的概念,但是有有效和无 ...
- javascript-实现小抽奖程序
直接上代码 <style> *{ margin: 0; padding:0;} .prize_wrap{ width: 300px; height: 150px; } .prize_wra ...
- 六款常见的Linux操作系统推荐
家常常可能因为工作或学习的需要,要使用个操作系统(比如Windows和Linux).大家对Windwos支持的文件系统可能比较熟悉,而对Linux操作系统所支持的文件系统也许比较陌生.下面小编为大家推 ...
- IDEA 编译时 未结束的字符串文字
这个问题就是编码的问题,修改文件的编码可以解决 1. IDEA中 file-->Settings 找到File Encodings,将IDE Encoding.Project Encodin ...
- HTTP与抓包
HTTP就是超文本传输协议,底层使用socket TCP长连接,基于请求与响应,是同步请求. socket 绝对多数语言都是支持socket的,底层走的是二进制传输. HTTP协议实际上是对Socke ...
- The revocation function was unable to check revocation for the certificate
https://stackoverflow.com/questions/45556189/git-the-revocation-function-was-unable-to-check-revocat ...
- Java编程时部分快捷键
alt + / 内容助理 配置:Window->properties->keys->查看alt + /的配置,然后解除当前的配置->搜索content assist->解 ...