題目連接node
原創的博客ios
題意:ide
超市裏有N個商品. 第i個商品必須在保質期(第di天)以前賣掉, 若賣掉可以讓超市得到pi的利潤。優化
天天只能賣一個商品。spa
如今你要讓超市得到最大的利潤。.net
n , p[i], d[i] 範圍都在10000之內 。3d
#include<iostream> #include<cstdio> #include <cctype> #include<algorithm> #include<cstring> #include<cmath> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #include<queue> #include<map> using namespace std; #define ll long long #define mem(a,x) memset(a,x,sizeof(a)) #define se second #define fi first const ll mod=998244353; const int INF= 0x3f3f3f3f; const int N=4e5+5; int n; priority_queue<int>q; vector<int>v[N]; int main() { while(cin>>n) { for(int i=1;i<=10001;i++) v[i].clear() ; priority_queue<int>empty; swap(empty, q); //至關於清空q。 for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); v[y].push_back(x); } int ans=0; for(int i=10005;i>=1;i--) { for(int j=0;j<v[i].size();j++) { q.push(v[i][j]); } if(!q.empty()) { ans+=q.top(); q.pop(); } } printf("%d\n",ans); } }
用另外一種貪心的方法來作,先把全部產品按照利潤從大到小排序,而後這個把這個放在截止日期那天賣出,並作好標記,若是截至日期那天已經有其餘產品佔用了,那麼能夠把這個產品賣出的時間往前推,直到找到能夠賣的那一天並標記好。 按照這種思路提交,AC了,不過卻用了141 ms。code
用了這個方法以後,再回想了下並查集方法的代碼, 所謂的用並查集作,其實是對上面那種方法的優化!
用並查集的關鍵之處是,咱們知道按照上面那個方法,假設一個產品a佔用了一個日期後,那麼若是下次又有一個產品b和產品a的截止日期是相同的,可是那個日期以被佔用了,因此就要往前移動1天,那麼就能夠用並查集進行標記,在a佔用了那個日期後,把a的截止日期指向前一個日期,這樣的話,能夠直接查找到他要佔用到哪個時間。 用了並查集優化後,時間爲47MS。blog
---------------------
做者:shuangde800
來源:CSDN
原文:https://blog.csdn.net/shuangde800/article/details/8022068 排序
#include<iostream> #include<cstdio> #include <cctype> #include<algorithm> #include<cstring> #include<cmath> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #include<queue> #include<map> using namespace std; #define ll long long #define mem(a,x) memset(a,x,sizeof(a)) #define se second #define fi first const ll mod=998244353; const int INF= 0x3f3f3f3f; const int N=4e5+5; int n; //vector<int>v[N]; int vis[N]; struct node { int p,d; }a[N]; bool cmp(node x,node y) { return x.p>y.p || x.p==y.p&&x.d>y.d; } int main() { while(cin>>n) { for(int i=1;i<=10005;i++) vis[i]=0; int maxT=0; for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].p,&a[i].d); if(maxT<a[i].d) maxT=a[i].d; } sort(a+1,a+1+n,cmp); int ans=0; for(int i=1;i<=n;i++) { if(!vis[a[i].d ]) { vis[a[i].d ]=1; ans+=a[i].p; } else{ for(int j=a[i].d; j>=1;j--) { if(!vis[j]) { vis[j]=1; ans+=a[i].p; break; } } } } cout<<ans<<endl; } }
#include<iostream> #include<cstdio> #include <cctype> #include<algorithm> #include<cstring> #include<cmath> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #include<queue> #include<map> using namespace std; #define ll long long #define mem(a,x) memset(a,x,sizeof(a)) #define se second #define fi first const ll mod=998244353; const int INF= 0x3f3f3f3f; const int N=4e5+5; int n; int f[N]; struct node { int p,d; }a[N]; bool cmp(node x,node y) { return x.p>y.p; } int getf(int x) { if(x!=f[x]) { f[x]=getf(f[x]); } return f[x]; } int main() { while(cin>>n) { for(int i=1;i<=10005;i++) f[i]=i; int maxT=0; for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].p,&a[i].d); if(maxT<a[i].d) maxT=a[i].d; } sort(a+1,a+1+n,cmp); int ans=0; for(int i=1;i<=n;i++) { int fa=getf(a[i].d); if(fa>0) { ans+=a[i].p; f[fa]=fa-1; } } cout<<ans<<endl; } }