【学术篇】SDOI2009 学校食堂
传送门~
题目大意
先分析\((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 学校食堂的更多相关文章
- BZOJ 1226: [SDOI2009]学校食堂Dining
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 730 Solved: 446[Submit][ ...
- 【题解】Luogu P2157 [SDOI2009]学校食堂
原题传送门:P2157 [SDOI2009]学校食堂 一看题目就知道是状压dp 设f[i][j][k]表示第1到i-1个人都吃完了饭,第i个人以及后面的7个人是否打饭的状态为j,当前最后打饭的人的编号 ...
- 【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 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
- P2157 [SDOI2009]学校食堂
题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
- P2157 [SDOI2009]学校食堂 (dp+状态压缩)
题目链接:传送门 题目: 题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人 ...
- P2157 [SDOI2009]学校食堂Dining
题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
- 【bzoj1226】【[SDOI2009]学校食堂Dining】状压dp
(上不了p站我要死了,侵权度娘背锅) Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人 ...
随机推荐
- shell提取rpm的报名
说明: rpm本身未安装,下面方法是基于rpm包文件实现提取rpm的包名 rpm -qpi ZXVEi-git0/CgsOS/abrt-2.1.11-48.el7.centos.x86_64.rpm ...
- 39-Ubuntu-用户管理-04-usermod设置主组和附加组
主组:通常在新建用户时指定,在/etc/passwd的第4列GID显示主组名. 附加组:在/etc/group中最后一列显示该组的用户列表,用于指定用户的附加权限. 1.修改用户的主组 sudo us ...
- 我的vscode配置 利用Settings Sync一键安装
{ "prettier.eslintIntegration": true, // 点击保存时,根据 eslint 规则自定修复,同时集成 prettier 到 eslint 中 & ...
- 内网渗透_win_socks代理_reGeorg+proxifier
遇到内网windows机器,如果想远程登陆,通常得通过代理,常用的nc.lcx 工具可满足要求. 如 lcx 示例: 两台机器上均上传lcx.exe 在 xp机器(公网)上执行 lcx.exe -li ...
- Java oop 第13章_多线程
第13章_多线程 一. 多线程相关的概念: 程序:由某种编程语言开发可执行某些功能的代码组合,它是静态的概念. 进程:当程序被执行时的过程可以理解为讲程序从外存调入内存的过程,会为每一个程序 ...
- java.sql.Date和java.util.Date的联系和区别
1) java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的瘦包装器,允许 JDBC 将毫秒值标识为 SQL DATE 值.毫秒值表示自 1970 年 1 月 1 日 0 ...
- Jenkins忘记 admin 密码
进入 jenkins home(我的是/var/jenkins_home)路径下的users 文件夹 cd /var/jenkins_home/users sudo vim admin/config. ...
- Burnside引理&Pólya定理
Burnside's lemma 引例 题目描述 一个由2*2方格组成的正方形,每个格子上可以涂色或不涂色, 问共有多少种本质不同的涂色方案. (若两种方案可通过旋转互相得到,称作本质相同的方案) 解 ...
- top.location.href
window.location.href.location.href是本页面跳转 parent.location.href是上一层页面跳转 top.location.href是最外层的页面跳转 ...
- SolidWorks新建三维零件
1.创建工作目录. 2.新建一个零件三维模型文件. 3.创建零件中的各个特征 (1).创建第一个特征(基础特征) ①选择命令 ②创建截面草图 定义草图平面 定义截面草图 完成草图 ③定义深度等属性 定 ...