【题解】SDOI2009学校食堂
不知道有没有人跟我有一样的感觉……实际上很多的状压DP都不难,然而调到心碎……这题题面看起来很长,还有混合的‘位运算’来吓唬人(实际上就是异或而已)。但实际上只要仔细阅读,发现也是一道水水的裸题。
首先,题目当中给出的信息是:\(B_{i} <= 7\)。看到这一条,心中已有八分笃定:在这样的环境下,估计是状压。然后就开始考虑转移的方程: 先从暴力的状态开始,我们要确定没有后效性的状态,则有两个维度应该是必须的。一维代表 \(i\),即现在 \(1 -> i\) 之间的同学都已经打到饭了,以及 \(j\) 即上一名打饭的同学的口味值。最后的一维状压,压 \(\left (i + 1, i + 8 \right )\) 号同学的打饭状态,后面的就不用了,因为第 \(i + 1\) 个人目前还没有打到饭,他最大只能容忍第 \(i + 8\) 名同学先打。
可是出现了一个问题:\(j\)的范围过大。所以不能存值,只能存编号。考虑在第\(i + 1\) 个人还没有打饭的情况下,上一个打饭的人只能在范围 \(\left (i - 7, i + 8 \right )\) 中,我们存下这一个编号,并且规定一个标准:第 \(i\) 名同学的编号为 \(7\)。这样,所有可能的同学编号均在 \(\left (0, 15 \right )\) 的范围内。
感觉我的状压dp代码有毒……食用需谨慎呐 ̄へ ̄
#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
#define INF 9999999
int T, CNST;
int n, a[maxn], t[maxn];
int f[maxn][][]; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void Init()
{
for(int i = ; i <= n; i ++)
for(int j = ; j <= ; j ++)
for(int k = ; k < CNST; k ++)
f[i][j][k] = INF;
} void update(int &x, int y) { x = x < y ? x : y; } int main()
{
T = read(), CNST = ( << ) - ;
while(T --)
{
n = read();
Init();
for(int i = ; i <= n; i ++) a[i] = read(), t[i] = read();
f[][][] = ;
for(int i = ; i < n; i ++)
for(int k = ; k < CNST; k ++)
{
for(int j = ; j <= ; j ++)
{
if(f[i][j][k] >= INF) continue;
int tmp = k, minn = INF;
for(int s = ; s <= && (i + s + ) <= n; s ++)
if(!((tmp >> s) & )) minn = min(minn, s + t[i + s + ]);
if(minn == INF || k & ) minn = ;
for(int s = ; s <= minn; s ++)
{
if((k >> s) & ) continue;
if(i + s + > n) break;
int q = i + j - >= ? a[i + j - ] : ;
if(!i && !k) q = a[i + s + ];
int ret = q ^ a[i + s + ];
if(s + <= ) update(f[i][s + ][k | ( << s)], f[i][j][k] + ret);
}
int q = (i + j - ) >= ? a[i + j - ] : ;
if(!i && !k) q = a[i + ];
update(f[i + ][][k >> ], f[i][j][k] + (q ^ a[i + ]));
if(j && (k & )) update(f[i + ][j - ][k >> ], f[i][j][k]);
}
}
int ans = INF;
for(int j = ; j <= ; j ++)
for(int k = ; k < CNST; k ++)
ans = min(ans, f[n][j][k]);
printf("%d\n", ans);
}
return ;
}
【题解】SDOI2009学校食堂的更多相关文章
- 【题解】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 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满 ...
- BZOJ 1226: [SDOI2009]学校食堂Dining
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 730 Solved: 446[Submit][ ...
- P2157 [SDOI2009]学校食堂Dining
题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
- BZOJ1226 [SDOI2009]学校食堂Dining 【状压dp】
题目 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示 ...
- luogu2157 [SDOI2009]学校食堂 局部状压
题目大意 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
- [LuoguP2157][SDOI2009]学校食堂_状压dp
学校食堂 题目链接:https://www.luogu.org/problem/P2157 数据范围:略. 题解: 发现$B$特别小,很容易想到状压. 即在$dp$的时候弄出来$f_{(i,j,k)} ...
- 1226: [SDOI2009]学校食堂Dining - BZOJ
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)
Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...
- [SDOI2009]学校食堂Dining
题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...
随机推荐
- vue兄弟组件传值$on多次执行的问题
首先附上如何进行兄弟组件通信的方法链接 https://segmentfault.com/a/1190000011882494 下面是$on多次执行的解决办法 https://blog.csdn.ne ...
- Pro Git 学习笔记
Pro Git 学习笔记 文档地址:Pro Git原文地址:PRO GIT 学习笔记 git常见命令 1.Git起步 初次运行Git前的配置 用户信息 git config --global user ...
- 使用deque保留有限的记录
# 使用deque保留有限的记录 >>> from collections import deque >>> q = deque(maxlen=3) # 指定队列的 ...
- python并发编程之多进程、多线程、异步、协程、通信队列Queue和池Pool的实现和应用
什么是多任务? 简单地说,就是操作系统可以同时运行多个任务.实现多任务有多种方式,线程.进程.协程. 并行和并发的区别? 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任 ...
- ThinkPhP html原样入库
开始正式搞php,在配置好PHP环境之后,从学习thinkphp框架开始php之旅. 在实际项目中需要将一个网页的html保存到数据库中,但不能被转义.由于thinkphp的数据库操作为通过他们自己O ...
- Java常考面试题
Java常考面试题 1. 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? 答:Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行 ...
- 使用USB Key(加密狗)实现身份认证
首先你需要去买一个加密狗设备,加密狗是外形酷似U盘的一种硬件设备! 这里我使用的坚石诚信公司的ET99产品 公司项目需要实现一个功能,就是客户使用加密狗登录, 客户不想输入任何密码之类的东西,只需要插 ...
- 「日常训练」「小专题·USACO」 Wormholes(1-4)
题意 之后补充. 分析 这是一条很好的考察递归(或者说搜索)的题目.它的两个过程(建立初步解,验证)都用到了递归(或者说运用递归可以相当程度的减少代码量). 具体实现见代码.注意,为了使用std::p ...
- Python 3基础教程18-获取用户键盘输入
有时候,我们需要获取用户的键盘输入的信息,然后得到信息,拿去做一些事情. 请看下面的demo.py # 练习如何通过键盘获取用户输入 x = input('What is your name?') p ...
- python学习总结----内置函数及数据持久化
抽象基类(了解) - 说明: - 抽象基类就是为了统一接口而存在的 - 它不能进行实例化 - 继承自抽象类的子类必须实现抽象基类的抽象方法 - 示例: from abc import ABC, abs ...