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是可以重复选取的, ...
随机推荐
- PAT L2-024 部落
https://pintia.cn/problem-sets/994805046380707840/problems/994805056736444416 在一个社区里,每个人都有自己的小圈子,还可能 ...
- 封装day.js
封装day.js import dayjs from 'dayjs' import 'dayjs/locale/zh-cn' import relativeTime from 'dayjs/plugi ...
- asp.net mvc area实现多级controller和多级view
经常需要描述这样的项目结构 ~:. //web根目录├─.admin //管理员功能目录│ └─index.html //管理员目录页面├─.user / ...
- 数据处理 array json 格式 转换成 数组形式
处理这种数据应该使用的方式是 this.cities= res.data.data.cities.sort((a,b)=>{ //排序 进行字母排序 return a.pinyin[0].cha ...
- asp.net core下一个简单的分页技术
在做web应用的时候免不了要对数据进行分页,我最近在做asp.net core的开发的时候就遇到了这个需求,现在简单的记录一下: public class PaginatedList<T> ...
- CMake--常用指令
1 . ADD_DEFINITIONS 向 C/C++ 编译器添加 -D 定义,比如 在CMakeList.txt文件中添加: ADD_DEFINITIONS(-DENABLE_DEBUG -DABC ...
- 在linux上安装MySQL数据库,并简单设置用户密码,登录MySQL
在新装的Centos系统上安装MySQL数据库. <p><a href="http://www.cnblogs.com/tijun/">提君博客原创< ...
- GitHub创建仓库,并与git本地仓库关联
登录后头像右上角点击: 起名再create 后 会跳转到下面页面: 先在git上复制执行第一条指令,创建一个readme文档 然后再用第二条初始化仓库 第三步将readme文档添加至暂存区 然后提交一 ...
- 莫烦theano学习自修第一天【常量和矩阵的运算】
1. 代码实现如下: #!/usr/bin/env python #! _*_ coding:UTF-8 _*_ # 导入numpy模块,因为numpy是常用的计算模块 import numpy as ...
- python数学第六天【指数族】