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. 设计模式(三) cglib代理

    1.1.cglib代理,也可也叫子类代理 Cglib代理,也叫做子类代理.我们知道,JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能使用JDK的动态代理.cglib是针对类来实现代 ...

  2. nginx3

    Yum安装更简单.安装并启动keepalived,表示安装成功.有3个进程. etc\keepalived\keepalived.conf: 备的keepalived配置文件: ! Configura ...

  3. hadoop28---netty传对象

    Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象.基于 ...

  4. ES6数组的扩展--Array.from()和Array.of()

    一. Array.from() : 将伪数组对象或可遍历对象转换为真数组 1.何为伪数组 如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为"类 ...

  5. c++中小项堆声明和使用

    c++默认是大顶堆,小顶堆有两种声明方法: 1.对于基本类型直接用 priority_queue<int, vector<int>, greater<int> >p ...

  6. How to create and manage configuration backups in Internet Information Services 7.0

    https://support.microsoft.com/en-us/help/954872/how-to-create-and-manage-configuration-backups-in-in ...

  7. CocoaPods学习系列4——进阶用法

    这篇文章,记录一下CocoaPods的进阶用法. 进阶用法主要体现在.podspec文件和Podfile的配置上. .podspec文件的进阶配置 以官方的一个.podspec文件示例细说: Pod: ...

  8. flume-ng源码阅读memory-channel(原创)

    org.apache.flume.channel.MemoryChannel类是Flume-NG的memory-channel. private LinkedBlockingDeque<Even ...

  9. InfiniBand技术和协议架构分析

    Infiniband开放标准技术简化并加速了服务器之间的连接,同时支持服务器与远程存储和网络设备的连接. IB技术的发展 1999年开始起草规格及标准规范,2000年正式发表,但发展速度不及Rapid ...

  10. 《JavaScript高级程序设计》第7章 函数表达式

    定义函数的方式有两种:函数声明和函数表达式 // 函数声明 function function_name(argument) { // body... } // 函数表达式 var function_ ...