D. Recommendations

https://codeforces.com/contest/1315/problem/D

题意:给出一个n,表示有n类书,然后接下来有两行,一行是某一类书的数量;一行是对应的书的整理时间;

要求:1.每一类书的数量都不同。 2.只有增加书的数量这一操作。

思路:对于这样一个序列,自然是整理时间长的放在前面是最优解,所以我们根据时间从大到小排序,根据数量从小到大排序;

然后遍历一遍,当遇到没有出现过的vis,可以直接用;

假如遇到出现过的,我们就遍历比这个数大的数,假如遇到没有用过的,这个数就是此类书最后的数量,然后更新权值即可;

这个时候,我们就需要记录一下刚才走过的点,然后将刚才的点的nxt数组标记为没有用过的这个点+1;

防止超时;

代码如下

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=2e5+10;
 5 int tmpsto[maxn];
 6 map<int,int>vis;
 7 map<int,int>nxt;
 8 struct node
 9 {
10     int num;
11     int t;
12 }a[maxn];
13 bool cmp(node x,node y)
14 {
15     if(x.t==y.t) return x.num<y.num;
16     else return x.t>y.t;
17 }
18 int main()
19 {
20     int n;
21     scanf("%d",&n);
22     for(int i=1;i<=n;i++)
23         scanf("%d",&a[i].num);
24     for(int i=1;i<=n;i++)
25         scanf("%d",&a[i].t);
26     sort(a+1,a+1+n,cmp);
27     ll cost=0;
28     for(int i=1;i<=n;i++){
29         if(vis[a[i].num]){
30             int base=a[i].num;
31             int num=0;
32             while(vis[base]){
33                 tmpsto[++num]=base;
34                 if(!nxt[base]){
35                     base++;
36                 }
37                 else base=nxt[base];
38             }
39             cost+=1ll*(base-a[i].num)*a[i].t;
40             vis[base]=1;
41             for(int i=1;i<=num;i++)
42                 nxt[tmpsto[i]]=base+1;
43         }
44         else{
45             vis[a[i].num]=1;
46         }
47     }
48     printf("%lld\n",cost);
49     return 0;
50 }

猜你喜欢

转载自www.cnblogs.com/pangbi/p/12389294.html
今日推荐