链接:https://www.nowcoder.com/acm/contest/212/C
来源:牛客网
题目描述
听说彩虹有七种颜色?
一维坐标轴上n条线段,每条线段左端点l,右端点r,颜色为c,从中选m种颜色的互不接触的线段,每种颜色可选多条,所选线段的总长度最长为多少?
输入描述:
第一行2个整数 n, m; 接下来n行,每行3个整数l, r, c。
输出描述:
一个整数,表示所选线段的最长的总长度;若选不了,输出-1;
示例1
输入
复制
4 2 1 3 1 4 5 1 5 8 2 7 9 3
输出
复制
5
示例2
输入
复制
4 3 1 3 1 4 5 1 5 8 2 7 9 3
输出
复制
-1
备注:
1 <= n <= 100000; 1 <= m <= 7; 1 <= l < r <= 1000000000; 1 <= c <= 7;
dp操作
#include<bits/stdc++.h>
#include<stdlib.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=b-1;i>=a;--i)
#define lowbit(x) (x&(-x))
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
const LL INF=1e18;
const int N=100010;
struct Seg {
LL l,r;
int c;
Seg(LL _l=0,LL _r=0,int _c=0)
{
l=_l,r=_r,c=_c;
}
bool operator<(const Seg& b)const
{
if(r==b.r)return l<b.l;
return r<b.r;
}
} p[N];
int has[2*N];
unordered_map<int,int> pos;
LL dp[4*N][130];
int num[10];
LL ans=-1;
int n,m;
int vec[10],vis[10];
int cnt;
void solve()
{
int tmp=0;
for(int i=0; i<m; i++)tmp=tmp|(1<<(vec[i]-1));
ans=max(ans,dp[cnt-1][tmp]);
}
void dfs(int tot,int pos)
{
if(tot==m) {
solve();
return;
}
if(pos>7)return;//!!!越界应该 在后面,不是在最前面,否则会出现漏掉情况的可能
dfs(tot,pos+1);//不存在,需要单独列出来
if(num[pos]) {
vec[tot]=pos;
vis[pos]=1;
dfs(tot+1,pos+1);
vis[pos]=0;
}
}
int main()
{
// freopen("123.txt","r",stdin);
//freopen("789.txt","w",stdout);
while(scanf("%d %d",&n,&m)==2) {
ans=-1;
pos.clear();
for(int i=1; i<=n; i++) {
int l,r,c;
scanf("%d %d %d",&l,&r,&c);
num[c]++;
p[i]=Seg(l,r,c);
has[(i-1)*2]=l,has[(i-1)*2+1]=r;
}
sort(p+1,p+n+1);
//rep(i,1,n+1)printf("i:%d %lld %lld\n",i,p[i].l,p[i].r);
has[2*n]=0;
sort(has,has+2*n+1);
cnt=unique(has,has+2*n+1)-has;
for(int i=0; i<cnt; i++)pos[has[i]]=i;
//rep(j,0,cnt)printf("j:%d %d\n",j,has[j]);
int t=1<<7;
for(int i=0; i<=cnt; i++)for(int j=0; j<=t; j++)dp[i][j]=-INF;
//for(int j=0;j<=t;j++)dp[0][j]=0;
dp[0][0]=0;
int id=1;
for(int i=1; i<cnt; i++) {
while(id<=n&&p[id].r<=has[i]) {
for(int j=0; j<t; j++) {
if(dp[pos[p[id].l]-1][j]==-INF)continue;
int dif=p[id].c-1;
int t=j|(1<<dif);
dp[i][t]=max(dp[i][t],dp[pos[p[id].l]-1][j]+(p[id].r-p[id].l));
//printf("i:%d j:%d t:%d dp[i][t]:%lld\n",i,j,t,dp[i][t]);
}
//printf("i:%d id:%d \n",i,id);
id++;
}
for(int j=0; j<t; j++) {
dp[i][j]=max(dp[i][j],dp[i-1][j]);
}
}
dfs(0,1);
printf("%lld\n",ans);
}
return 0;
}