Luogu 2157 [SDOI2009]学校食堂 - 状压dp
Solution
比较好想的dp, 但是坑不少QAQ, 调半天
由于容忍度 $b_i$<= 7, 所以可以考虑将第$i$个人接下来的$b_i$ 个人作为一个维度记录状态。
于是我们定义数组$f[ i ][ S ]$ 表示前$i-1$个人都已经拿到了菜, S表示$i$和接下来$b_i$个人是否拿到了菜。
然后依次枚举$i$ :第$i$个人, $S$ : $i$与接下来$b_i$个人是否拿到菜, $nt$ : 下一次谁拿菜, $fr$ : 上一次谁拿菜
还需要通过$judge$来判断该状态是否可行, 最后进行$dp$
具体看代码里的$jud$ 和$dp$ 函数
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rd read()
#define rep(i,a,b) for(register int i = (a); i <= (b); ++i)
#define per(i,a,b) for(register int i = (a); i >= (b); --i)
using namespace std; const int N = 1e3 + ;
const int base = ;
const int inf = ; int tas[N], bac[N], f[N][][];
int n, T; int read() {
int X = , p = ; char c = getchar();
for(; c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(; c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} int jud(int now, int S, int nt, int fr) {
if(f[now][S][fr +base] >= inf) return ;
if((S >> nt) & ) return ;
if(!((S >> fr) & ) && fr >= ) return ;
if(now + fr < ) return ;
rep(i, now, now + nt) if(!((S >> (i - now)) & ) && now + nt > i + bac[i]) return ;
return ;
} void dp(int now, int S, int nt, int fr) {
int ntS = S | ( << nt), tmp = inf; //ntS表示给nt拿完菜的状态
if(now + fr) tmp = min(tmp, f[now][S][fr + base] + (tas[now + nt] ^ tas[now + fr]));
else tmp = min(tmp, f[now][S][fr + base] + );
nt += now;
for(; ntS & ; ntS >>= ) {
f[now][ntS][nt - now + base] = min(f[now][ntS][nt - now + base], tmp);
//printf("%d %d %d\n", now, ntS, nt);
now++;
}
f[now][ntS][nt - now + base] = min(f[now][ntS][nt - now + base], tmp);
//printf("%d %d %d\n", now, ntS, nt);
} void work() {
memset(f, , sizeof(f));
n = rd;
rep(i, , n) tas[i] = rd, bac[i] = rd;
f[][][- + base] = ;
rep(i, , n) rep(j, , ( << (bac[i] + )) - ) rep(k, , bac[i]) rep(fr, -, ) {//fr必须从-8枚举
if(!jud(i, j, k, fr)) continue;
dp(i, j, k, fr);
}
int ans = inf;
rep(i, -, ) ans = min(ans, f[n][][i + base]);
printf("%d\n", ans);
} int main()
{
T = rd;
rep(i, , T) work();
}
Luogu 2157 [SDOI2009]学校食堂 - 状压dp的更多相关文章
- P2157 [SDOI2009]学校食堂 状压DP
题意: 排队买饭,时间为前一个人和后一个人的异或和,每个人允许其后面B[i] 个人先买到饭,问最少的总用时. 思路: 用dp[i][j][k] 表示1-i-1已经买好饭了,第i个人后面买饭情况为j,最 ...
- BZOJ 1226 学校食堂(状压DP)
状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...
- bzoj1226/luogu2157 学校食堂 (状压dp)
我们先约定:(左) 窗口_人人人人人 (右) 可以发现,我们只需要知道最靠左的还没打饭的人 以及它身后7个人的状态 以及上一个打饭的人是谁 因为他左面的就都打过了 右面7个人以后肯定还没打 可以设f[ ...
- SDOI 2009 学校食堂 状压dp
这个题的关键处1 紧跟着他的bi个人 —— 由此得出任意一个状态都可以表示为 有第一个人没吃到饭做分隔的前面所有人已吃饭,并用1<<8表示之后的(包括他)的八个人的状态2 信息仍然是上一个 ...
- 【题解】Luogu P2157 [SDOI2009]学校食堂
原题传送门:P2157 [SDOI2009]学校食堂 一看题目就知道是状压dp 设f[i][j][k]表示第1到i-1个人都吃完了饭,第i个人以及后面的7个人是否打饭的状态为j,当前最后打饭的人的编号 ...
- BZOJ1226或洛谷2157 [SDOI2009]学校食堂
BZOJ原题链接 洛谷原题链接 注意到\(B[i]\)很小,考虑状压\(DP\). 设\(f[i][j][k]\)表示前\(i - 1\)个人已经拿到菜,第\(i\)个人及其后面\(7\)个人是否拿到 ...
- [学习笔记]状压dp
状压 \(dp\) 1.[SDOI2009]Bill的挑战 \(f[i][j]\) 表示匹配到字符串的第 \(i\) 位状态为 \(j\) 的方案数 那么方程就很明显了,每次枚举第 \(i\) 位的字 ...
- 洛谷 P3112 后卫马克 —— 状压DP
题目:https://www.luogu.org/problemnew/show/P3112 状压DP...转移不错. 代码如下: #include<iostream> #include& ...
- 洛谷 3112 [USACO14DEC]后卫马克Guard Mark——状压dp
题目:https://www.luogu.org/problemnew/show/P3112 状压dp.发现只需要记录当前状态的牛中剩余承重最小的值. #include<iostream> ...
随机推荐
- 过滤access日志前5条数据
cat /usr/local/nginx/logs/access.log|awk '{print $1}'|sort|uniq -c|sort -n -r|head -5 找不到的话可以find查找a ...
- 用R画韦恩图
#导入R包 library(grid)library(futile.logger)library(VennDiagram) #建立测试数据集 A = 1:150B = c(121:170,300:32 ...
- w3af的使用
编解码工具 配置身份 基本身份认证 明文用base64编码 NTML认证方式,微软特有的加密方式 form表单身份认证 这样基于表单的认证就配置好了 基于cookie认证 点击后面的感叹号,它会有co ...
- 581. Shortest Unsorted Continuous Subarray
Given an integer array, you need to find one continuous subarray that if you only sort this subarr ...
- typedef void (*Fun) (void) 的理解——函数指针——typedef函数指针
首先介绍大家比较熟悉的typedef int i;//定义一个整型变量i typedef myInt int: myInt j;//定义一个整型变量j 上面介绍得是我们常用的比较简单的typedef的 ...
- 200. Number of Islands (Graph)
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...
- H5入门
1.基本骨架 <!DOCTYPE html> <html> <head><title>标题</title><meta charset= ...
- JavaScript各种继承方式(四):原型式继承(prototypal inheritance)
一 原理 利用工具函数,通过原型对象直接得到父类的实例,并当作子类对实例使用. function inherit(obj){ // 在闭包中创建子类,对外隐藏子类 function Temp(){ } ...
- RocketMQ-quickstart(批量消费)
一.专业术语 Producer 消费生产者,负责产生消息,一般由业务系统负责产生消息 Consumer 消息消费者,负责消费消息,一般是后台系统负责异步消费 Push Consumer Consume ...
- iOS - iphoneX系列 - 全局配置的基本信息
/// 获得当前窗口 var JY_WINDOW: UIWindow? { get{ if let app = UIApplication.shared.delegate as? AppDeleg ...