一个显而易见的 dp,一看题就能想到,况且 m≤200 已经提示的够明显了。
不过是细节稍微有几处,把思路理清就没问题。
下面是我的代码,做法还是很简单的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
const int maxn=1e5+5,maxm=205;
pi pre[maxn];
vector<pi>add[maxn],del[maxn];
ll dp[maxn][maxm];
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n,m,k;cin>>n>>m>>k;
int s,t,d,w;
for(int i=1;i<=k;i++){
cin>>s>>t>>d>>w;
add[s].emplace_back(w,d);
del[t].emplace_back(w,d);
}
multiset<pi>now;
for(int i=1;i<=n;i++){
for(pi j:add[i]) now.insert(j);
if(now.size()) pre[i]=*(--now.end());
for(pi j:del[i]) now.erase(now.find(j));
}
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++) dp[i][j]=1e15;
}
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(dp[i][j]==1e15) continue;
if(pre[i+1].first){
dp[pre[i+1].second][j]=min(dp[pre[i+1].second][j],dp[i][j]+pre[i+1].first);
}
else dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
if(i<n and j<m) dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
}
}
ll ans=1e15;
for(int i=0;i<=m;i++) ans=min(ans,dp[n][i]);
cout<<ans<<"\n";
return 0;
}