标签:
Description
Input
Output
Sample Input
4 50 2 10 1 20 2 30 1 7 20 1 2 1 10 3 100 2 8 2 5 20 50 10
Sample Output
80 185
1 本题完全可以贪心解决,按照价值从大到小进行排列,每次取最大的价值,从他结束的时间开始向前暴力,如果有时间可以使用,没被vis数组标记,就可以再次位置进行
2 上述是贪心的思想,下面可以使用并查集进行优化,还是按照价值问题进行排列,每次回溯,找前面有一个点father【i】==i,那么此点可以使用,就可以停止进行,此外此点自己--
表示该时间也被使用,后面如果回溯到该点的时候不可以停止下来,仍然需要向前回溯,如果一直回溯到0,那么就是没有位置可以进行,那么这次的价值也不会算到总和里面
下面分别贴上两种代码
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int maxn=10005; struct node{ int t; int price; }que[maxn]; bool vis[maxn]; bool cmp(const struct node t1,const struct node t2){ if(t1.price==t2.price) return t1.t>t2.t; return t1.price>t2.price; } int main(){ int n; while(scanf("%d",&n)!=EOF){ memset(vis,false,sizeof(vis)); for(int i=0;i<n;i++){ scanf("%d%d",&que[i].price,&que[i].t); } sort(que,que+n,cmp); int sum=0; for(int i=0;i<n;i++){ int tmp_t=que[i].t; for(int j=tmp_t;j>=1;j--){ if(!vis[j]){ vis[j]=true; sum+=que[i].price; break; } } } printf("%d\n",sum); } return 0; }
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int maxn=10005; int father[maxn]; struct node{ int value; int t; }que[maxn]; void init(){ for(int i=0;i<maxn;i++) father[i]=i; } bool operator <(const node& t1,const node& t2){ if(t1.value!=t2.value) return t1.value>t2.value; return t1.t>t2.t; } int get_father(int x){ if(father[x]!=x) father[x]=get_father(father[x]); return father[x]; } int main(){ int n; while(scanf("%d",&n)!=EOF){ init(); for(int i=0;i<n;i++){ scanf("%d%d",&que[i].value,&que[i].t); } sort(que,que+n); int ans=0; for(int i=0;i<n;i++){ int tmp=que[i].t; int x=get_father(tmp); if(x>0){ father[x]--; ans+=que[i].value; } } printf("%d\n",ans); } return 0; }
POJ 1456 Supermarket 区间问题并查集||贪心
标签:
原文地址:http://www.cnblogs.com/13224ACMer/p/5014672.html