题目大意:给定图片说明 部电影,影片放映时间图片说明 ,对应图片说明 次影片放映的开始时间.求在图片说明 时间内可以连续观看电影的最少数量.(一部电影放映时可以切换另一部正在放映的电影)
图片说明
分析:状压dp

  • 图片说明 小于等于20,可以枚举所有选电影的方案.图片说明 表示图片说明 状态下连续放电影的结束时间.
  • 考虑图片说明 的转移,图片说明 方案没有选的电影就是二进制位下为0的位置图片说明 ,因为图片说明 的放映时间是图片说明
    所以我们只要找到第图片说明 部电影放映时间在 图片说明之前即可.因为暴力枚举会TLE,而且给出放映时间的是单调递增,所以我们二分找即可.
  • 答案就是所有符合图片说明 状态的下标图片说明 的二进制下图片说明 个数最小值.
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn=1<<21;

int dp[maxn];
int d[22],c[22],b[22][1005];

int main()
{
    int n,l;
    cin>>n>>l;
    for( int i=1;i<=n;i++ )
    {
        cin>>d[i]>>c[i];
        for( int j=1;j<=c[i];j++ ) cin>>b[i][j];
    }
    int ans=1e9;
    for( int i=0;i<1<<n;i++ )
    {
        for( int j=1;j<=n;j++ )
        {
            if( i>>(j-1) & 1 ) continue;
            int k=(i|(1<<(j-1)));
            int idx=upper_bound(b[j]+1,b[j]+1+c[j],dp[i])-b[j];
            idx--;
            if( idx>0 ) dp[k]=max(dp[k],b[j][idx]+d[j]);
        }
        if( dp[i]>=l ) 
        {
            int res=__builtin_popcount(i);
            ans=min(ans,res);
        }
    }


    if( ans==(int)1e9 ) puts("-1");
    else printf("%d\n",ans); 
}