Time Limits: 1000 ms  Memory Limits: 131072 KB
Description
在炽热的核熔炉中,居住着一位少女,名为灵乌路空。
据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量——核能。
核焰,可融真金。
咳咳。
每次核融的时候,空都会选取一些原子,排成一列。然后,她会将原子序列分成一些段,并将每段进行一次核融。
一个原子有两个属性:质子数和中子数。
每一段需要满足以下条件:
1、同种元素会发生相互排斥,因此,同一段中不能存在两个质子数相同的原子。
2、核融时,空需要对一段原子加以防护,防护罩的数值等于这段中最大的中子数。换句话说,如果这段原子的中子数最大为x,那么空需要付出x的代价建立防护罩。求核融整个原子序列的最小代价和。
第一行一个正整数N,表示原子的个数。
接下来N行,每行两个正整数pi和ni,表示第i个原子的质子数和中子数。
Output
输出一行一个整数,表示最小代价和。
| 12
 3
 4
 5
 6
 
 | 53 11
 2 13
 1 12
 2 9
 3 13
 
 | 
Sample Output
Data Constraint
对于20%的数据,1<=n<=100
对于40%的数据,1<=n<=1000
对于100%的数据,1<=n<=10^5,1<=pi<=n,1<=ni<=2*10^4
Code
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 
 | #include<stdio.h>#include<set>
 using namespace std;
 multiset<int>t;
 int tmp,n,m,ans=0,start,end;
 int data[100005],a[100005],b[100005],hou[100005],l[100005];
 int sum[100005],wei[100005],f[100005];
 int main()
 {
 freopen("array.in","r",stdin);
 freopen("array.out","w",stdout);
 scanf("%d",&n);
 for (int i=1;i<=n;i++){
 scanf("%d%d",&a[i],&b[i]);
 }
 for (int i=1;i<=n;i++){
 l[i]=hou[a[i]]+1,hou[a[i]]=i;
 }
 for (int i=1;i<=n;i++){
 l[i]=max(l[i-1],l[i]);
 }
 start=1;
 for (int i=1;i<=n;i++)
 {
 tmp=i-1;
 while(start<end&&wei[start+1]<l[i])
 {
 t.erase(t.find(sum[start]));
 start++;
 }
 while(start<=end&&b[i]>data[end])
 {
 t.erase(t.find(sum[end]));
 tmp=wei[end];
 end--;
 }
 data[++end]=b[i];
 wei[end]=tmp;
 if(start!=end)
 {
 sum[end]=f[wei[end]]+data[end];
 t.insert(sum[end]);
 t.erase(t.find(sum[start]));
 }
 sum[start]=f[l[i]-1]+data[start];
 t.insert(sum[start]);
 f[i]=*t.begin();
 }
 printf("%d\n",f[n]);
 }
 
 | 
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 暗影小站! 注: 本博客暂不开设评论区,请使用邮件119548583@qq.com联系