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. 链接指示:extern "C"

    C++程序有时需要调用其他语言编写的函数,最常见的是调用C语言编写的函数.像所有其他名字一样,其他语言中的函数名字也必须在C++中进行声明,并且该声明必须指定返回类型和形参列表.对于其他语言编写的函数 ...

  2. Mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

    Mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) Linux: MyS ...

  3. 关于JS解析编历JSON数组(含多维数组)

    第一部分:      ].xing) 第二部分:                         }    解释:    countryObj 为value对象的一个属性明    value[coun ...

  4. python3爬虫全国地址信息

    PHP方式写的一团糟所以就用python3重写了一遍,所以因为第二次写了,思路也更清晰了些. 提醒:可能会有502的错误,所以做了异常以及数据库事务处理,暂时没有想到更好的优化方法,所以就先这样吧.待 ...

  5. No module named bz2

    yum install bzip* python2.6 import bz2 python2.7 import bz2 error 解决:sudo cp /usr/lib64/python2.6/li ...

  6. 20145217《网络对抗》 MSF基础应用

    20145217<网络对抗> MSF基础应用 MSF基础应用 1.实践任务 任务一:ms08_067渗透攻击 任务二:IE浏览器渗透攻击--MS12063安全漏洞 任务三:adobe渗透攻 ...

  7. vue脚手架解决跨域问题-------配置反向代理

    1.打开config/index.js 2.在dev配置对象中找到proxyTable:{} 3.添加如下配置 // 配置反向代理,解决跨域请求 proxyTable: { '/api': { tar ...

  8. Spring框架下Junit测试

    Spring框架下Junit测试 一.设置 1.1 目录 设置源码目录和测试目录,这样在设置产生测试方法时,会统一放到一个目录,如果没有设置测试目录,则不会产生测试代码. 1.2 增加配置文件 Res ...

  9. Hibernate多对多关系映射

    两张表的多对多关系,在数据库中通常是通过第三张中间表来实现的,第三张中间表放的是两张表各自的主键值,通过主键与主键的对应来体现表直接的关系.比如在权限系统中,一个用户可以拥有多种权限,而一种权限也可以 ...

  10. Oracle操作ORA-02289: 序列不存在

    解决方案:实现创建序列,创建语句如下所示: create sequence employees_seq minvalue maxvalue start increment cache ; 这时候再执行 ...