建议降蓝
查看原帖
建议降蓝
571147
zhlzt楼主2025/1/3 09:56

一个显而易见的 dp,一看题就能想到,况且 m200m\le 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;
}
2025/1/3 09:56
加载中...