並查集做法:
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 50005
long long f[N];
pair <long long ,long long > m[N]; //作爲結構體的作用 第一個爲first 第二個爲 second 按frist排序 小到大
int find(int x){
if(x<=0) return -1; //這是邊界 如果在最遲時間前都沒有時間做這件事 就不再執行這個任務
if(x==f[x]) return f[x]=x-1; //並查集 實現 一個狀態的(存進去就有) 位置的存放
else return find(f[x]); //如果沒有找到 該點所放的位置 就接着找前面的位置
}
int main(){
long long n,sum=0;
cin>>n;
for(int i=0;i<n;i++){
f[i]=i;
cin>>m[i].second>>m[i].first;
m[i].first=-m[i].first; // 將值反過來 就變成了 從大到小的排序了 巧妙 不用定義bool判斷排序了
if(m[i].second>n) m[i].second=n; //只能從n開始向下找
}
sort(m,m+n);//排序一下
f[n]=n;
for(int i=0;i<n;i++){
if(find(m[i].second)>=0) //就存入該店的最大值
sum-= m[i].first;
}
cout<<sum<<endl;
return 0;
}
#include<iostream>
#include<algorithm>
using namespace std;
struct act{
long long x,y;
}a[50005];
bool book[50005];
bool cmp(act a,act b){
if(a.y==b.y) return a.x<b.x; //獎勵相等按時間小的排
return a.y>b.y;
}
int main(){
int n;
long long ans=0;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i].x>>a[i].y;
sort(a,a+n,cmp);
//for(int i=0;i<n;i++) cout<<a[i].x<<" "<<a[i].y<<endl; //輸出
for(int i=0;i<n;i++){ //在獎勵優先的情況下 放任務
int k=a[i].x;
while(k){// 意思就是在k之前的幾個時間裏放任務
if(!book[k]){ //是否放了任務 如果沒有放任務 就在時間點放下任務
book[k]=1; //放過
ans+=a[i].y; //獎勵的累計
break; //該獎勵已經找到地方放了
}
else k--; //該點沒有找到 就放之前的地方
} //對k之前的時間段放任務
}
cout<<ans<<endl;
return 0;
}
/*
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
*/