博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj3886】[Usaco2015 Jan]Moovie Mooving 状态压缩dp+二分
阅读量:5025 次
发布时间:2019-06-12

本文共 2694 字,大约阅读时间需要 8 分钟。

题目描述

Bessie is out at the movies. Being mischievous as always, she has decided to hide from Farmer John for L (1 <= L <= 100,000,000) minutes, during which time she wants to watch movies continuously. She has N (1 <= N <= 20) movies to choose from, each of which has a certain duration and a set of showtimes during the day. Bessie may enter and exit a movie at any time during one if its showtimes, but she does not want to ever visit the same movie twice, and she cannot switch to another showtime of the same movie that overlaps the current showtime. Help Bessie by determining if it is possible for her to achieve her goal of watching movies continuously from time 0 through time L. If it is, determine the minimum number of movies she needs to see to achieve this goal (Bessie gets confused with plot lines if she watches too many movies).

PoPoQQQ要在电影院里呆L分钟,这段时间他要看小型电影度过。电影一共N部,每部都播放于若干段可能重叠的区间,PoPoQQQ决不会看同一部电影两次。现在问他要看最少几部电影才能度过这段时间? 注:必须看电影才能在电影院里呆着,同时一场电影可以在其播放区间内任意时间入场出场。

输入

The first line of input contains N and L. The next N lines each describe a movie. They begin with its integer duration, D (1 <= D <= L) and the number of showtimes, C (1 <= C <= 1000). The remaining C integers on the same line are each in the range 0..L, and give the starting time of one of the showings of the movie. Showtimes are distinct, in the range 0..L, and given in increasing order. 

输出

A single integer indicating the minimum number of movies that Bessie
needs to see to achieve her goal.  If this is impossible output -1
instead.

样例输入

4 100

50 3 15 30 55
40 2 0 65
30 2 20 90
20 1 0

样例输出

3


题解

状态压缩dp

设f[i]为状态i时最多能持续的时间。

那么就有f[i] = max(f[i] , a[j][k] + t[j]) (i&(1<<(j-1))==1,k为第一个使得a[j][k]>=f[i ^ (1 << (j - 1))]的数)。

于是二分查找即可,时间复杂度O(2^n*n*logd),看似很大,而亲测可过。

#include 
#include
using namespace std;int f[1050000] , t[21] , d[21] , a[21][1001] , num[1050000];int search(int p , int x){ int l = 1 , r = d[p] , mid , ans = -1; while(l <= r) { mid = (l + r) >> 1; if(a[p][mid] <= x) ans = mid , l = mid + 1; else r = mid - 1; } return ans;}int main(){ int n , m , i , j , k , ans = 0x7fffffff; scanf("%d%d" , &n , &m); for(i = 1 ; i <= n ; i ++ ) { scanf("%d%d" , &t[i] , &d[i]); for(j = 1 ; j <= d[i] ; j ++ ) scanf("%d" , &a[i][j]); } for(i = 1 ; i < 1 << n ; i ++ ) { for(j = 1 ; j <= n ; j ++ ) { if(i & (1 << (j - 1))) { k = search(j , f[i ^ (1 << (j - 1))]); if(k != -1) f[i] = max(f[i] , a[j][k] + t[j]); } } } for(i = 1 ; i < 1 << n ; i ++ ) { num[i] = num[i - (i & (-i))] + 1; if(f[i] >= m) ans = min(ans , num[i]); } printf("%d\n" , ans == 0x7fffffff ? -1 : ans); return 0;}

 

转载于:https://www.cnblogs.com/GXZlegend/p/6421226.html

你可能感兴趣的文章
高效的jQuery
查看>>
ubuntu 16.04 (软件应用)-输入法
查看>>
windos7修复引导扇区
查看>>
Leetcode总结之Backtracking
查看>>
Android开发学习之路-图片颜色获取器开发(1)
查看>>
StackExchange.Redis 官方文档(一) Basics
查看>>
nupkg 之破解 nodejs+electron-packager 打包exe的解包
查看>>
Objective-C 使用 C++类
查看>>
浅谈之高级查询over(partition by)
查看>>
Notes: CRM Analytics–BI from a CRM perspective (2)
查看>>
graphite custom functions
查看>>
列出所有的属性键
查看>>
js获取请求地址后面带的参数
查看>>
[原创]使用java批量修改文件编码(ANSI-->UTF-8)
查看>>
设计模式のCompositePattern(组合模式)----结构模式
查看>>
二进制集合枚举子集
查看>>
磁盘管理
查看>>
SAS学习经验总结分享:篇二—input语句
查看>>
UIImage与UIColor互转
查看>>
RotateAnimation详解
查看>>