不知道有没有人跟我有一样的感觉……实际上很多的状压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学校食堂的更多相关文章

  1. 【题解】Luogu P2157 [SDOI2009]学校食堂

    原题传送门:P2157 [SDOI2009]学校食堂 一看题目就知道是状压dp 设f[i][j][k]表示第1到i-1个人都吃完了饭,第i个人以及后面的7个人是否打饭的状态为j,当前最后打饭的人的编号 ...

  2. 【BZOJ1226】[SDOI2009]学校食堂Dining 状压DP

    [BZOJ1226][SDOI2009]学校食堂Dining Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满 ...

  3. BZOJ 1226: [SDOI2009]学校食堂Dining

    1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 730  Solved: 446[Submit][ ...

  4. P2157 [SDOI2009]学校食堂Dining

    题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...

  5. BZOJ1226 [SDOI2009]学校食堂Dining 【状压dp】

    题目 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示 ...

  6. luogu2157 [SDOI2009]学校食堂 局部状压

    题目大意 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...

  7. [LuoguP2157][SDOI2009]学校食堂_状压dp

    学校食堂 题目链接:https://www.luogu.org/problem/P2157 数据范围:略. 题解: 发现$B$特别小,很容易想到状压. 即在$dp$的时候弄出来$f_{(i,j,k)} ...

  8. 1226: [SDOI2009]学校食堂Dining - BZOJ

    Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...

  9. bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)

    Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...

  10. [SDOI2009]学校食堂Dining

    题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...

随机推荐

  1. javascript--select标签的添加删除功能的使用

    在网页开发中,常常遇见这种问题,给定两个框,A和B,和几个图片按钮,A中存在几个操作,点击图片按钮,填加至B中,或者从B中移除等,这种效果如何实现,本文加以总结. 几种效果图如下: 原始图:      ...

  2. xpath技术解析xm文件(php)

    1.结合php dom技术的学习,得出一个结论:php dom技术可以跨层取出节点,但是不能保持层次关系,使用xpath可以很好地解决问题. *** xpath技术的核心思想:迅速简洁的定位你需要查找 ...

  3. Vue使用json-server来进行后端数据模拟

    正开发过程中 前后端分离或者不分离 ,接口多半是之后与页面的开发 ,所以建立rest的APL的接口 给前端提供虚拟的数据是非常必要的 所以这里我使用了json-server作为工具,支持CORS和JS ...

  4. 国内maven库链接地址,链接阿里的库,下载很快!!!

    <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http:/ ...

  5. python并发编程之多进程、多线程、异步、协程、通信队列Queue和池Pool的实现和应用

    什么是多任务? 简单地说,就是操作系统可以同时运行多个任务.实现多任务有多种方式,线程.进程.协程. 并行和并发的区别? 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任 ...

  6. 安装 Node.js v8.0 生产环境

    步骤://center os 上把apt-get换成yum 第一步:进入服务器升级工具包 sudo apt-get update 第二步:安装git  sudo apt-get install git ...

  7. ABAP CDS ON HANA-(11)ABAP CDSでの関連付け

    Association in ABAP CDS An association in CDS view joins different data sources. Defining and using ...

  8. The Road to learn React书籍学习笔记(第四章)

    高级React组件 本章将重点介绍高级 React 组件的实现.我们将了解什么是高阶组件以及如何实现它们.此外,我们还将深入探讨 React 中更高级的主题,并用它实现复杂的交互功能. 引用 DOM ...

  9. 如何保证HashMap线程安全

    可使用Java 1.5推荐的java.util.concurrent包ConcurrentHashMap来实现,内部不再使用类似HashTable的synchronized同步锁,而是使用Reentr ...

  10. python2.7练习小例子(四)

    4):题目:输入某年某月某日,判断这一天是这一年的第几天?     程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于2时需考虑多加一天. ...