版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82183106
【描述】
小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播放。他希望连续看 L 分钟的电影。因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他不希望重复看一部电影,所以每部电影他最多看一次,也不能在看一部电影的时候,换到另一个正在播放一样电影的放映厅。
请你帮助小石头让他重 0 到 L 连续不断的看电影,如果可以的话,计算出最少看几部电影。
【输入格式】
第一行是 2 个整数 N,L,表示电影的数量,和小石头希望看的连续时间
接下来是 N 行,每行第一个整数 D(1<=D<=L)表示电影播放一次的播放时间,第二个整数
是 C 表示这部电影有 C 次播放,接下来是 C 个整数表示 C 次播放的开始时间 Ti
(0<=Ti<=L) ,Ti 是按升序给出。
【输出格式】
一个整数,表示小石头最少看的电影数量,如果不能完成输出-1
【输入样例】
4 100
50 3 15 30 55
40 2 0 65
30 2 20 90
20 1 0
【输出样例】
3
【样例说明】
开始他选择最后一步电影从 0 时间开始。
到了 20 分钟,他选择第一部电影的第一次播放,看到 65 分钟
最后他选择第二部电影的第二次播放,从 65 分钟到 100 分钟
【数据规模】
30%数据 N<=10
100%数据 N<=20, 1 <= L <= 100,000,000 , C<=1000
解析:
好的又是一道状压 。
有两种做法,今天晚上更新。
代码(做法一,二分查找,建议把vector改成普通数组):
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define st static
inline
int getint(){
st int num;
st char c;
for(c=gc();!isdigit(c);c=gc());
for(num=0;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline
void outint(ll a){
st char ch[23];
if(a==0)pc('0');
while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
while(ch[0])pc(ch[ch[0]--]);
}
inline
int lowbit(int k){
return k&-k;
}
inline
int cntbit(int k){
int cnt;
for(cnt=0;k;k-=lowbit(k))++cnt;
return cnt;
}
int N,L;
int Ans=0x3f3f3f3f;
vector<ll> T[23];
int D[23];
ll f[1<<20];
bool vis[1<<20];
inline
int Find(int j,cs ll &key){
int l=0,r=T[j].size()-1;
if(T[j][0]>key||T[j].back()+D[j]<key)return -1;
while(l<r){
int mid=(l+r+1)>>1;
if(T[j][mid]==key)return mid;
if(T[j][mid]<key)l=mid;
else r=mid-1;
}
return l;
}
int main(){
N=getint();
L=getint();
for(int re i=1;i<=N;++i){
D[i]=getint();
int C=getint();
while(C--){
int tmp=getint();
T[i].push_back(tmp);
}
}
vis[0]=true;
f[0]=0;
for(int re i=0;i<(1<<N);++i){
if(cntbit(i)>=Ans){
i+=lowbit(i);
--i;
continue;
}
if(!vis[i])continue;
if(f[i]>=L){
Ans=min(Ans,cntbit(i));
continue;
}
for(int re j=1;j<=N;++j){
if(0!=(i&(1<<(j-1))))continue;
int pos=Find(j,f[i]);
if(pos==-1)continue;
if(T[j][pos]+D[j]>f[i]&&T[j][pos]<=f[i]){
f[i|(1<<(j-1))]=max(f[i|(1<<(j-1))],T[j][pos]+D[j]);
vis[i|(1<<(j-1))]=true;
}
}
}
if(Ans==0x3f3f3f3f){
puts("-1");
}
else {
outint(Ans);
}
return 0;
}