题解 B 七彩线段
七彩线段
https://ac.nowcoder.com/acm/contest/6607/B
状态压缩DP。
先将所有位置离散化,然后在每一个 的 vector 中插入 和 ,当枚举到 时,可以从 转移而来,令当前状态为 ,则 ,其中 表示离散化后某个位置代表的真实位置。
时间复杂度
#include<bits/stdc++.h> #define re //register using namespace std; inline int read(){ re int t=0;re char v=getchar(); while(v<'0')v=getchar(); while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar(); return t; } vector<int>v[200002]; int n,ans,m,a[100002],b[100002],c[100002],l[100002],r[200002],pos[200002],cnt,dp[200002][129]; signed main(){ n=read();m=read(); for(re int i=1;i<=n;++i){ a[i]=read(),b[i]=read(),c[i]=read(); r[++cnt]=a[i],r[++cnt]=b[i]; } sort(r+1,r+cnt+1); for(re int i=1;i<=n;++i)pos[lower_bound(r+1,r+cnt+1,a[i])-r]=a[i],a[i]=lower_bound(r+1,r+cnt+1,a[i])-r; for(re int i=1;i<=n;++i)pos[lower_bound(r+1,r+cnt+1,b[i])-r]=b[i],b[i]=lower_bound(r+1,r+cnt+1,b[i])-r; for(re int i=1;i<=n;++i)v[b[i]].push_back(a[i]),v[b[i]].push_back(c[i]); memset(dp,-127,sizeof(dp)); dp[0][0]=0; for(re int i=1;i<=cnt;++i){dp[i][0]=0; for(re int j=0;j<(1<<7);++j)dp[i][j]=dp[i-1][j]; for(re int j=0;j<v[i].size();j+=2){ re int x=v[i][j],y=v[i][j+1]; for(re int k=0;k<(1<<7);++k){ if((k&(1<<(y-1)))){ dp[i][k]=max(dp[i][k],max(dp[x-1][k],dp[x-1][(1<<(y-1))^k])+pos[i]-pos[x]); } } } } re int ans=0; for(re int i=0;i<(1<<7);++i)if(__builtin_popcount(i)==m)ans=max(ans,dp[cnt][i]); if(ans)printf("%d",ans);else puts("-1"); }