bzoj1226/luogu2157 学校食堂 (状压dp)
我们先约定:(左) 窗口_人人人人人 (右)
可以发现,我们只需要知道最靠左的还没打饭的人 以及它身后7个人的状态 以及上一个打饭的人是谁
因为他左面的就都打过了 右面7个人以后肯定还没打
可以设f[i][j][k]表示这是第i个人,身后7个人的状态是j,上一个打饭的是k
但其实上一个打饭的离他最远也就是8,所以可以只记i和k的差值,为了避免出负数再加个10之类的
考虑怎么转移,有两种情况
1.i身后的某个人打饭:找到j中是0的一位x,同时保证x左面的没打饭的人+这个人的容忍度<=x,也就是保证这个转移合法
2.i自己打饭:找到i右面第一个是0的位置,转移到这个位置
转移的时候更新一下k就好了
#include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
const int maxn=,maxs=,maxb=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,v[maxn],f[maxn][maxs][maxb],b[maxn],bin[maxb]; int gettime(int i,int j,int k){
return (i+k-)?(v[i+j]|v[i+k-])-(v[i+j]&v[i+k-]):;
} int main(){
//freopen("","r",stdin);
int i,j,k,l;
bin[]=;for(i=;i<=;i++) bin[i]=bin[i-]<<;
for(int T=rd();T;T--){
N=rd();
for(i=;i<=N;i++)
v[i]=rd(),b[i]=rd();
for(i=N+;i<=N+;i++)
b[i]=;
CLR(f,);
f[][][]=;int ans=1e9+;
for(i=;i<=N;i++){
for(j=;j<bin[b[i]+];j++){
for(k=;k<=+b[i];k++){
if(f[i][j][k]>=1e9) continue;
int mi=;
for(l=;l<=b[i]&&l<=mi;l++){
if(!(j&bin[l])) f[i][j|bin[l]][l+]=min(f[i][j|bin[l]][l+],f[i][j][k]+gettime(i,l,k));
if(!(j&bin[l])) mi=min(mi,l+b[i+l]);
}
for(l=;l<=b[i];l++)
if(!(j&bin[l])) break;
f[i+l][j>>l][-l]=min(f[i+l][j>>l][-l],f[i][j][k]+gettime(i,,k));
if(i+l>N) ans=min(ans,f[i+l][j>>l][-l]);
}
}
}
printf("%d\n",ans);
}
return ;
}
bzoj1226/luogu2157 学校食堂 (状压dp)的更多相关文章
- BZOJ 1226 学校食堂(状压DP)
状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...
- P2157 [SDOI2009]学校食堂 状压DP
题意: 排队买饭,时间为前一个人和后一个人的异或和,每个人允许其后面B[i] 个人先买到饭,问最少的总用时. 思路: 用dp[i][j][k] 表示1-i-1已经买好饭了,第i个人后面买饭情况为j,最 ...
- Luogu 2157 [SDOI2009]学校食堂 - 状压dp
Solution 比较好想的dp, 但是坑不少QAQ, 调半天 由于容忍度 $b_i$<= 7, 所以可以考虑将第$i$个人接下来的$b_i$ 个人作为一个维度记录状态. 于是我们定义数组$f[ ...
- SDOI 2009 学校食堂 状压dp
这个题的关键处1 紧跟着他的bi个人 —— 由此得出任意一个状态都可以表示为 有第一个人没吃到饭做分隔的前面所有人已吃饭,并用1<<8表示之后的(包括他)的八个人的状态2 信息仍然是上一个 ...
- [学习笔记]状压dp
状压 \(dp\) 1.[SDOI2009]Bill的挑战 \(f[i][j]\) 表示匹配到字符串的第 \(i\) 位状态为 \(j\) 的方案数 那么方程就很明显了,每次枚举第 \(i\) 位的字 ...
- bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- [luoguP2157] [SDOI2009]学校食堂Dining(状压DP)
传送门 这种鬼畜的状压DP...第一次见 看到 0 <= Bi <= 7 就应该想到状态压缩,然而此题实在太鬼畜,想到也没什么乱用 f[i][j][k]表示前i-1个人全部吃完,i~i+7 ...
- 【BZOJ1226】学校食堂(动态规划,状态压缩)
[BZOJ1226]学校食堂(动态规划,状态压缩) 题面 BZOJ 洛谷 题解 发现\(b\)很小,意味着当前这个人最坏情况下也只有后面的一小部分人在他前面拿到饭. 所以整个结果的大致顺序是不会变化的 ...
- 状压DP之LGTB 与序列
题目 思路 这道题竟然是状压DP,本人以为是数论,看都没看就去打下一题的暴力了,哭 \(A_i\)<=30,所以我们只需要考虑1-58个数,再往后选的话还不如选1更优,注意,1是可以重复选取的, ...
随机推荐
- Java.lang.OutOfMemoryError:Metaspace
Understand the OutOfMemoryError Exceptionhttps://docs.oracle.com/javase/8/docs/technotes/guides/trou ...
- java Date时间的各种转换方式和Mysql存时间类型字段的分析
一:各种Date之间的转换方法 public class TimeTest { public static void main(String[] args) { Date date = new Dat ...
- java语句中的重定向函数
重定向后面就不能转发了,所以return null
- Unit 1.前端基础之html
一.什么是html 定义:全称是超文本标记语言(HyperText Markup Language),它是一种用于创建网页的标记语言.标记语言是一种将文本(Text)以及文本相关的其他信息结合起来,展 ...
- flutter屏幕适配
现在的手机品牌和型号越来越多,导致我们平时写布局的时候会在个不同的移动设备上显示的效果不同, 比如我们的设计稿一个View的大小是300px,如果直接写300px,可能在当前设备显示正常,但到了其他设 ...
- IntelliJ IDEA启动Tomcat后,却无法访问Tomcat主页 等一系列问题
1.IntelliJ IDEA启动Tomcat后,却无法访问Tomcat主页 转:http://www.myexception.cn/other/1998827.html https://blog.c ...
- python爬虫之初始Selenium
1.初始 Selenium[1] 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Moz ...
- Python——Flask框架——模板
一.渲染模板 render_template 函数把Jinja2模板引擎集成到程序中 二.Jinja2变量过滤器 过滤器名 说明 safe 渲染值是不转义 capitalize 把值得首字母转换成大写 ...
- 待解决ava.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method)
java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at ja ...
- Jenkins+PowerShell持续集成环境搭建(一)前期准备
0. 系统要求 Windows Server:本文章使用的为Windows Server 2012 JDK:本文章使用为JDK 1.8 Windows PowerShell:本文章使用为PowerSh ...