标签:
Description
Input
Output
Sample Input
input | output |
---|---|
6 2
500 0
700 0
300 0
400 0
500 50
800 0
5 10
6 15
|
2680.00
|
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <cstring> #include <string> #include <algorithm> using namespace std; typedef long long ll; #define MM(a,b) memset(a,b,sizeof(a)); #define inf 0x7f7f7f7f #define FOR(i,n) for(int i=1;i<=n;i++) #define CT continue; #define PF printf #define SC scanf const int maxn=100000+10; struct node{ ll val;int id; bool operator<(const node &a) const{ return this->val>a.val; } }; vector<int> G[105]; priority_queue<node> q; int num[105],g[105]; int main() { int n,m; while(~SC("%d%d",&n,&m)){ ll ori=0,ans=0; for(int i=0;i<=100;i++) G[i].clear(); FOR(i,n) { int cost,p; SC("%d%d",&cost,&p); ori+=cost*(100-p); G[p].push_back(cost); } for(int i=0;i<=100;i++) sort(G[i].begin(),G[i].end()); MM(num,inf); FOR(i,m){ int peo,dis; SC("%d%d",&peo,&dis); num[dis]=min(num[dis],peo); } // PF("111111\n"); ans=ori; FOR(k,100){ if(num[k]>n) CT; MM(g,0); // PF("2222222\n"); ll tmp=ori,cnt=0; for(int i=0;i<=k;i++) for(int j=0;j<G[i].size();j++){ tmp+=G[i][j]*(i-k);cnt++; } // PF("3333333\n"); while(q.size()) q.pop(); for(int i=k+1;i<=100;i++) { if(G[i].size()) q.push((node){G[i][0]*(i-k),i}); g[i]=1; } // PF("444444\n"); while(cnt<num[k]){ node u=q.top();q.pop(); tmp+=u.val; cnt++; if(g[u.id]<G[u.id].size()){ int r=g[u.id]; q.push((node){G[u.id][r]*(u.id-k),u.id}); g[u.id]++; } } ans=min(ans,tmp); } PF("%.2f\n",(double)ans/100.00); } return 0; }
错点:如果直接枚举优惠券的优惠值大小k(0-100),然后,计算出每种票在此优惠券下的可优惠
价格,再sort排下序是100*1e5*log1e5是会超时的,所以需要优化一下,考虑买单个票的时候,打的折
<=k的必须要算(可优惠),对于>k的,对每种k,每次都只能选其中的一种(贪心),所以,可用优先队列将复杂度降到1e5log100,
注意==k的也必须要贪啊,,因为要让大与k的数量尽可能小
标签:
原文地址:http://www.cnblogs.com/smilesundream/p/5721538.html