传送门~

题目大意

先分析\((x\ or\ y)-(x\ and\ y)\), 就是\(x\)和\(y\)中存在的1减去\(x\)和\(y\)中相同的1 那不就是\(x\ xor\ y\)么←_←

给定\(n\)个人, 确定一个排列, 使得不存在\(i+b_i\)在\(i\)之前, 并最小化\(\sum_{i=2}^{n}t_i\ xor\ t_{i-1}\).

题目分析

\(1\leqslant b_i\leqslant7\), 数据范围一眼状压...

但是具体怎么定义状态呢?

假如说(最一般的想法)\(f_{i,j}\)表示到第\(i\)个人的时候(前\(i-1\)个人已经打完饭), 后面(包括他)的打饭集合为\(j\)(0表示没打 1表示打了)..

但是推的时候要涉及到上一个人的打饭状态...

而上一个打饭的人不一定是\(i-1\)

所以我们还要记录一下上一个打饭的人...

定义状态\(f_{i,j,k}\)表示前\(i-1\)个人都已经打完饭, \(i\sim i+7\)的打饭集合为\(j\), 上一个打饭的是\(i+k\).

很显然\(k=-8\sim 7\). 而由于c++数组的尿性, 我们要\(k+8\)再存

然后就是考虑递推了.

  • 初始化的话 因为要找最小值 全都赋值为\(\infty\)...

    边界条件\(f_{1,0,-1}=0\)显然.

  • 首先如果\(j\&1\neq 0\), 说明第\(i\)个人已经打饭了, 后面的人就不会跑到他前面...

    我们发现这个状态和 \(f_{i+1,j>>1,k-1}\) (第\(i+1\)个人打饭, 集合为去掉\(i\)后的状态, 最后一个打饭的人是\((i+1)+(k-1)\)是一样的.. 可以直接转移过去.

  • 如果\(j\&1=0\)呢? 说明第\(i\)个人还没有打饭. 那就不能转移到\(f_{i+1,?,?}\)了.

    我们就要从后面枚举一个人, 让他去打饭.

    我们可以\(1\sim 7\)枚举\(l\), 目标状态就是\(f_{i,j|(1<<l),l}\)...

    于是就出现了\(f_{i,j|(1<<l),l}=min\{f_{i,j,k}+t_{i+k}\ xor\ t_{i+l}\}\)...

    但是要注意第一道菜是不需要时间的, 所以要特判\(i+k=0\)的情况...

    然后要注意的就是枚举的这个人不能引起别人的愤怒...

    所以要维护一下能忍耐的范围...

    一旦不能忍耐了, 那就直接break掉就行.. 因为后面的更不行了...

  • 最后从\(f_{n+1,0,?}\)里面找个最小的作为\(ans\)就好了~

这样就做完了.

代码:

这种枚举变量个数多的dp用的tab缩进真是美如画..

#include <cstdio>
#include <cstring>
const int N=1002;
int f[N][260][17],t[N],b[N];
inline int gn(int a=0,char c=0){
for(;c<'0'||c>'9';c=getchar());
for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
}
inline int min(const int &a,const int &b){return a<b?a:b;}
void work(){
memset(f,0x3f,sizeof(f)); int n=gn();
for(int i=1;i<=n;++i) t[i]=gn(),b[i]=gn();
f[1][0][7]=0;
for(int i=1;i<=n;++i)
for(int j=0;j<256;++j)
for(int k=-8;k<8;++k)
if(f[i][j][k+8]<1e9){
if(j&1) f[i+1][j>>1][k+7]=min(f[i+1][j>>1][k+7],f[i][j][k+8]);
else{
int r=1e9;
for(int l=0;l<8;++l)
if(!(j&(1<<l))){
if(i+l>r) break;
if(i+l+b[i+l]<r) r=i+l+b[i+l];
f[i][j|(1<<l)][l+8]=min(f[i][j|(1<<l)][l+8],f[i][j][k+8]+(i+k?(t[i+k]^t[i+l]):0));
}
}
} int ans=1e9;
for(int i=-8;i<8;++i) ans=min(ans,f[n+1][0][i]); printf("%d\n",ans);
}
int main(){
int T=gn();
while(T--)work();
}

注意事项

注意事项应该都说过了...

可能要提醒的就是多组数据, 每次记得清理f数组...

然后就是该有的特判都不要少..

一定时刻记得第三维要+8哦~

完结撒花~

【学术篇】SDOI2009 学校食堂的更多相关文章

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

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

  2. 【题解】Luogu P2157 [SDOI2009]学校食堂

    原题传送门:P2157 [SDOI2009]学校食堂 一看题目就知道是状压dp 设f[i][j][k]表示第1到i-1个人都吃完了饭,第i个人以及后面的7个人是否打饭的状态为j,当前最后打饭的人的编号 ...

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

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

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

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

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

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

  6. [SDOI2009]学校食堂Dining

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

  7. P2157 [SDOI2009]学校食堂

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

  8. P2157 [SDOI2009]学校食堂 (dp+状态压缩)

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

  9. P2157 [SDOI2009]学校食堂Dining

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

  10. 【bzoj1226】【[SDOI2009]学校食堂Dining】状压dp

    (上不了p站我要死了,侵权度娘背锅) Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人 ...

随机推荐

  1. 引入scss(@import)和其中易错点

    1.引入文件方式 @import 'url'; ./ :当前目录 ../ :上级目录 src/api/styles: 绝对路径 2.一般在main.js中引用当做全局样式 import 'styles ...

  2. redis 配置文件aof配置

    redis 配置文件aof配置: bind 127.0.0.1 port 6379 daemonize yes dbfilename dump.rdb dir /new_renpeng/redis/ ...

  3. HTML中<frameset>标签不显示的问题

    啥都不说,先上代码 <html> <head> <title>index</title> <meta content = 'text/html'; ...

  4. scala 列表List

    列表: 列表是不可变,也就是说不能通过赋值改变列表的元素: 列表有递归结构,而数据是连续的 List 类型:List() 同样也是List(String) 列表是基于Nil (是空的)和::(列表从前 ...

  5. 深入理解JAVA虚拟机原理之垃圾回收器机制(一)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 对于程序计数器.虚拟机栈.本地方法栈这三个部分而言,其生命周期与相关线程有关,随 ...

  6. .net 委托 +lamda表达式

    1.委托与类同级 想当于定义了一个类型 如 delegate int Sum(int a, int b);// 在声明类之前声明 2.这里可以在类里写个函数 public int sumAB(int ...

  7. 关于版本管理工具SVN

    曾经使用过Git,但是目前使用的是相对简单的svn. 刚使用的时候,如果不出意外.会有同学配好环境与权限. 前端只需要将代码下载,修改,更新,与上传. 一 .下载 1.本地新建文件夹,作为本地仓库 命 ...

  8. DNF邀请码开发再开发方案需求

    一.原因分析:   1.现实原因:主播粉丝量级有限,一定规模粉丝注册消耗完后无法进 行之后合作 2.主播资源有限,能合作主播数量少   3.直播粉丝真实接近核心用户,但是不能将其有效转化为平台流水   ...

  9. 使用Swagger2Markup归档swagger生成的API文档

    文章出处: http://blog.didispace.com/swagger2markup-asciidoc/ 说明 项目中使用Swagger之后,我们能够很轻松的管理API文档,并非常简单的模拟接 ...

  10. runtime和runloop问答

    Runtime 01 问题: objc在向一个对象发送消息时,发生了什么? 解答: 根据对象的 isa 指针找到类对象 id,在查询类对象里面的 methodLists 方法函数列表,如果没有在好到, ...