CF1889C题解
CF1889C 题解
题意
有
做法
考虑 dp,把所有线段按照左端点从小到大排序,令
注意 unordered_map
记录。
转移可以枚举当前线段是否删除,是
实现细节
dp 数组只开一个 unordered_map
,可以把三维压一起,这样不用担心开
转移完一个状态后就可以把它从哈希表里删除,这样同一时刻的哈希表里的元素个数仅有
注意不要
总复杂度时间
代码
unordered_map<int,int>dp;
int n,m,k;
pii p[200005];
//i*(k+1)*(n+1)+j*(n+1)+k
const int C=100000000;
inline void go(int x,int y,int z,int t){
int w=(x<<22)|(y<<18)|z;
Mi(dp[w],t-C);
}
void run(){
cin>>n>>m>>k;
rep(i,m){
cin>>p[i].F>>p[i].S;
}
if(k>=m){
cout<<n<<"\n";
re;
}
sort(p,p+m);
dp.clear();
set<int>st;
st.insert(0);
int ans=n+1;
go(0,0,0,0);
rep(i,m){
for(int l:st)rep(j,min(k,i)+1)if(dp.count((i<<22)|(j<<18)|l)){
int t=dp[(i<<22)|(j<<18)|l]+C;
dp.erase((i<<22)|(j<<18)|l);
// cout<<i<<" "<<j<<" "<<l<<": "<<t<<"\n";
go(i+1,j,max(l,p[i].S),t+max(p[i].S,l)-max(p[i].F-1,l));
if(j<k)go(i+1,j+1,l,t);
}
st.insert(p[i].S);
while(sz(st)>k+1)st.erase(st.begin());
}
for(int l:st)rep(j,k+1){
// cout<<m<<" "<<j<<" "<<l<<": "<<dp[(m<<22)|(j<<18)|l]+C<<"\n";
Mi(ans,dp[(m<<22)|(j<<18)|l]+C);
}
cout<<n-ans<<"\n";
}