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的更多相关文章

  1. [SDOI2009][BZOJ 1226]学校食堂

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

  2. bzoj [SDOI2009]学校食堂Dining

    感觉这个状压dp比较难想.. dp[ i ][ s ][ k ] 表示前i - 1个都排好了, 从i开始的7个的取没取的状态为s, 且最后一个相对i的位置为k的最少花费. 状态转移方程 if(s &a ...

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

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

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

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

  5. BZOJ-1226 学校食堂Dining 状态压缩DP

    1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...

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

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

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

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

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

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

  9. [SDOI2009]学校食堂Dining

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

随机推荐

  1. linux---(6/27)tr命令和sed命令详解

    Tr命令: tr是简单的单个“字符”处理工具,而sed是功能非常强大的“字符串”处理工具. 用于查询,字符串2用于处理各种转换.tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始 ...

  2. Django学习笔记之Django视图View

    一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...

  3. oracle 11 g数据库卸载(方法二)

    1.开始->设置->控制面板->管理工具->服务 停止所有 Oracle服务. 2.开始->程序->Oracle - OraHome81->Oracle In ...

  4. Vmware ESXi 6.0 多Vlan部署,vSphere Client管理方法

    背景: 公司IT部门新购了两台服务器与一台存储,打算做虚拟化,并将存储分成两个部分,分别配给那两台服务器.在宿主机上要安装的虚拟机属于不同的网段,这就涉及了多VLAN,当然这并不是多么高深的技术,属于 ...

  5. CSV文件导入导出MySQL

    使用SQLyog 工具导入文件数据到MySQL: Excel文件导入导出: 需要驱动:Microsoft Office 2007驱动 导入需要注意的问题:1.Excel里数值列,默认导入会变成浮点型. ...

  6. Go语言学习之常量(The way to go)

    生命不止,继续go go go . 上一篇博客<Go语言学习之变量(The way to go)介绍了go中的变量,今天就介绍常量. const关键字 跟c++中一样,go中同样具有const关 ...

  7. SpringBoot 通用Error设计

    在项目中需要设计统一的错误消息,通常使用枚举类定义"错误码"与"错误消息": 并且也可以做错误消息自定义. 定义通过错误接口类:CommonError publ ...

  8. TeamViewer---Linux远程控制利器

    TeamViewer中国官网 TeamViewer用户手册 参考链接一 参考链接二 参考链接三:每天一个linux命令(41):ps命令 简介 TeamViewer是一个远程控制软件,兼容于Micro ...

  9. EF Code-First 学习之旅 级联删除

    级联删除是当删除主记录的时候会自动删除依赖的记录或者设置外键属性为null public class Student { public Student() { } public int Student ...

  10. centos 安装jdk/resin/mysql

    一.安装JDK 1.判断是否安装 java -version 我的计算机上使用java -version命令,内容如下: java version "1.7.0_45"OpenJD ...