32 条题解
- 
  2PowderHan LV 10 @ 2018-08-20 09:16:25 /* 20%的数据:随便搞搞 40%的数据:同上 60%的数据:枚举N次,每次枚举每一户人家,判断这一户人家是否被推销过, 找到选择哪一户人家会得到最大的疲劳值,累加到ans里即可。 注意:若选择在当前已选最靠右的一户人家(设为x)的左边的人家(设为y), 则答案只需要增加推销这户人家的疲劳值(即ans=ans+A[y])。 而选择x右边的人家(设为z),则答案需要增加多出来的走路疲劳值和推销这户人家的疲劳值 (即ans=ans+(d[z]-d[x])*2+A[z])。时间复杂度O(n2) 100%的数据:和60分数据差不多, 将枚举每一户人家改为用堆维护已选的最右边的那户人家(设为x)的左边推销疲劳值的最大值( 设为堆D1)和x的右边推销疲劳值加上来回走路疲劳值的最大值(设为堆D2)。 那么每次的答案就是ans=ans+max(D1[1],D2[1]-d[x]*2)。 求答案之前要判断D1[1]和D2[1]是否合法 (即D1[1]所对应的点在x左边且没选过,D2[1]所对应的点在x的右边且没选过)。 时间复杂度O(n log2 n)。 做模拟比赛的时候想了半天 想到了线段树? 然后线段树没有滑稽币不会啊 然后就果断打了个60分暴力QAQ 然后考完一看 这个堆优化不是很容易想到吗 唉果然被普及组吓坏了 都不敢想高级算法了直接交了个暴力 Orz我好害怕 说说我的理解吧 我们很容易看到 其实对于选择n个这个问题 可以贪心的 不难想到 X= i 时的最优方案一定从 X = i-1 时的最优方案的基础上再加一户宣传对象得来。 考虑 X = 1 时的选择,显然是所有住户中 Ai + 2Si 中最大的被选, 若有多个住户的 Ai + 2Si 相同,则优先选择 Si 最小的(想一想为什么)。 然后序列被划分成左右两个部分,选择左边住户获得 Ai 的贡献, 选择右边住户获得 Ai + 2(Si - T) 的贡献,T 表示当前划分界限到胡同入口的距离, 注意右边部分的贡献的大小关系相比最初并没有改变,只需要重新对左边住户的贡献进行排序。 于是可以建一个新优先队列将左边的所有住户加入,将原优先队列中被划分到左边部分的元素丢掉。 因为划分界线是一直往右移的,所以每个元素至多被加入两次,被删除两次, 说白了就是我们每次选一个最优 只有可能是两种情况 1.继续向右走扩大距离(这个情况肯定是要选择能得到最大疲劳值的点) 2.不继续向右走了(那么我们就直接在左边选一个推销疲劳值的最大的点了) 两种情况去最大就好了 考虑到范围很大 加了个堆(优先队列)优化咯 Orz就这样没了 */ #include <cstdio> #include <queue> using namespace std; const int MAXN=100010; int d[MAXN],a[MAXN]; int Last,Next,n,Sum,Best; priority_queue<int> q;//堆用来维护已选的最右边的点左边的最大值 void init() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&d[i]); for(int i=1;i<=n;i++) scanf("%d",&a[i]); } void solve() { Next=0;//Next用来记录下下一个最右边点的位置 for(int k=1;k<=n;k++) { Last=Next;//已选的最右边的点 if(!q.empty())//q非空(即不是第一次) Best=q.top()+d[Last]*2;//因为sum中只保存了所有选取的疲劳值而为保存走路的疲劳值 //就是直接选取了左边的最优解 else Best=0; for(int i=Last+1;i<=n;i++)//尝试右边可不可以更新最大疲劳值 if(a[i]+d[i]*2>Best) { Best=a[i]+d[i]*2; Next=i;//记录下更新的右边的店 } printf("%d\n",Sum+Best); if(Next==Last)//如果没有更新到最右边的点 { Sum+=q.top();//就直接选取堆中的点 q.pop();//选完了出栈 } else//说明选取的是右边的点 { for(int i=Last+1;i<Next;i++)//更新了最右边的点那么左边的点要跟到来入栈 q.push(a[i]); Sum+=a[Next];//选上了这个点 } } } int main() { init(); solve(); return 0; }
- 
  2@ 2017-07-26 11:35:21相同的代码,codeVS上满分,这里10分。。。 
 还又WA又T。。。
 求大神帮忙看看有什么问题#include<bits/stdc++.h> 
 using namespace std;
 int a[100100],b[100100];
 bool f[100100];
 int maxi,len1,len2;
 struct node{
 int id;
 int sum;
 }c[100100],d[100100];
 int cmp(node x,node y){
 return x.sum<y.sum;
 }
 void built1(int beg,int en){
 len1=0;
 for(int i=beg;i<=en;i++)
 if (f[i]==true){
 c[i-beg+1].id=i;
 c[i-beg+1].sum=b[i];
 len1++;
 }
 make_heap(c+1,c+len1+1,cmp);
 }
 void built2(int beg,int en){
 len2=0;
 for(int i=beg;i<=en;i++)
 if (f[i]==true){
 d[i-beg+1].id=i;
 d[i-beg+1].sum=b[i]+(a[i]-a[maxi])*2;
 len2++;
 }
 make_heap(d+1,d+len2+1,cmp);
 }
 int main(){
 int n;
 cin>>n;
 for(int i=1;i<=n;i++)
 cin>>a[i];
 maxi=1;
 for(int i=1;i<=n;i++){
 cin>>b[i];
 if(a[i]*2+b[i]>a[maxi]*2+b[maxi]) maxi=i;
 }
 memset(f,true,sizeof(f));
 int total=a[maxi]*2+b[maxi];
 cout<<total<<endl;
 f[maxi]=false;
 built1(1,maxi-1);
 built2(maxi+1,n);
 int left=1;int right=n;
 for(int i=1;i<n;i++){
 int p,pmax;
 int q,qmax;
 pmax=c[1].sum;p=c[1].id;
 qmax=d[1].sum;q=d[1].id;
 int xb,m;
 if (pmax>qmax){
 xb=p;
 m=pmax;
 pop_heap(c+1,c+len1+1,cmp);
 len1--;
 }else{
 xb=q;
 maxi=q;
 m=qmax;
 f[q]=false;
 built1(left,maxi-1);
 built2(maxi+1,right);
 }
 total+=m;
 f[xb]=false;
 while(f[left]==false) left++;
 while(f[right]==false) right--;
 cout<<total<<endl;
 }
 return 0;
 }#1 Accepted 2ms 384.0KiB 
 #2 Wrong Answer 3ms 464.0KiB
 #3 Wrong Answer 3ms 384.0KiB
 #4 Wrong Answer 3ms 384.0KiB
 #5 Wrong Answer 13ms 500.0KiB
 #6 Wrong Answer 2ms 384.0KiB
 #7 Wrong Answer 59ms 1.375MiB
 #8 Time Exceeded ≥1005ms ≥1.691MiB
 #9 Time Exceeded ≥1003ms ≥2.621MiB
 #10 Time Exceeded ≥1001ms ≥1.965MiB测试点#salesman1.in 结果:AC 内存使用量: 360kB 时间使用量: 1ms 
 测试点#salesman10.in 结果:AC 内存使用量: 3692kB 时间使用量: 310ms
 测试点#salesman2.in 结果:AC 内存使用量: 360kB 时间使用量: 1ms
 测试点#salesman3.in 结果:AC 内存使用量: 364kB 时间使用量: 1ms
 测试点#salesman4.in 结果:AC 内存使用量: 360kB 时间使用量: 1ms
 测试点#salesman5.in 结果:AC 内存使用量: 364kB 时间使用量: 2ms
 测试点#salesman6.in 结果:AC 内存使用量: 364kB 时间使用量: 3ms
 测试点#salesman7.in 结果:AC 内存使用量: 3944kB 时间使用量: 319ms
 测试点#salesman8.in 结果:AC 内存使用量: 3948kB 时间使用量: 299ms
 测试点#salesman9.in 结果:AC 内存使用量: 3692kB 时间使用量: 299ms
- 
  1@ 2022-07-20 13:49:00/* 20%的数据:随便搞搞 40%的数据:同上 60%的数据:枚举N次,每次枚举每一户人家,判断这一户人家是否被推销过, 找到选择哪一户人家会得到最大的疲劳值,累加到ans里即可。 注意:若选择在当前已选最靠右的一户人家(设为x)的左边的人家(设为y), 则答案只需要增加推销这户人家的疲劳值(即ans=ans+A[y])。 而选择x右边的人家(设为z),则答案需要增加多出来的走路疲劳值和推销这户人家的疲劳值 (即ans=ans+(d[z]-d[x])*2+A[z])。时间复杂度O(n2) 100%的数据:和60分数据差不多, 将枚举每一户人家改为用堆维护已选的最右边的那户人家(设为x)的左边推销疲劳值的最大值( 设为堆D1)和x的右边推销疲劳值加上来回走路疲劳值的最大值(设为堆D2)。 那么每次的答案就是ans=ans+max(D1[1],D2[1]-d[x]*2)。 求答案之前要判断D1[1]和D2[1]是否合法 (即D1[1]所对应的点在x左边且没选过,D2[1]所对应的点在x的右边且没选过)。 时间复杂度O(n log2 n)。 做模拟比赛的时候想了半天 想到了线段树? 然后线段树没有滑稽币不会啊 然后就果断打了个60分暴力QAQ 然后考完一看 这个堆优化不是很容易想到吗 唉果然被普及组吓坏了 都不敢想高级算法了直接交了个暴力 Orz我好害怕 说说我的理解吧 我们很容易看到 其实对于选择n个这个问题 可以贪心的 不难想到 X= i 时的最优方案一定从 X = i-1 时的最优方案的基础上再加一户宣传对象得来。 考虑 X = 1 时的选择,显然是所有住户中 Ai + 2Si 中最大的被选, 若有多个住户的 Ai + 2Si 相同,则优先选择 Si 最小的(想一想为什么)。 然后序列被划分成左右两个部分,选择左边住户获得 Ai 的贡献, 选择右边住户获得 Ai + 2(Si - T) 的贡献,T 表示当前划分界限到胡同入口的距离, 注意右边部分的贡献的大小关系相比最初并没有改变,只需要重新对左边住户的贡献进行排序。 于是可以建一个新优先队列将左边的所有住户加入,将原优先队列中被划分到左边部分的元素丢掉。 因为划分界线是一直往右移的,所以每个元素至多被加入两次,被删除两次, 说白了就是我们每次选一个最优 只有可能是两种情况 1.继续向右走扩大距离(这个情况肯定是要选择能得到最大疲劳值的点) 2.不继续向右走了(那么我们就直接在左边选一个推销疲劳值的最大的点了) 两种情况去最大就好了 考虑到范围很大 加了个堆(优先队列)优化咯 Orz就这样没了 */ #include <cstdio> #include <queue> using namespace std; const int MAXN=100010; int d[MAXN],a[MAXN]; int Last,Next,n,Sum,Best; priority_queue<int> q;//堆用来维护已选的最右边的点左边的最大值 void init() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&d[i]); for(int i=1;i<=n;i++) scanf("%d",&a[i]); } void solve() { Next=0;//Next用来记录下下一个最右边点的位置 for(int k=1;k<=n;k++) { Last=Next;//已选的最右边的点 if(!q.empty())//q非空(即不是第一次) Best=q.top()+d[Last]*2;//因为sum中只保存了所有选取的疲劳值而为保存走路的疲劳值 //就是直接选取了左边的最优解 else Best=0; for(int i=Last+1;i<=n;i++)//尝试右边可不可以更新最大疲劳值 if(a[i]+d[i]*2>Best) { Best=a[i]+d[i]*2; Next=i;//记录下更新的右边的店 } printf("%d\n",Sum+Best); if(Next==Last)//如果没有更新到最右边的点 { Sum+=q.top();//就直接选取堆中的点 q.pop();//选完了出栈 } else//说明选取的是右边的点 { for(int i=Last+1;i<Next;i++)//更新了最右边的点那么左边的点要跟到来入栈 q.push(a[i]); Sum+=a[Next];//选上了这个点 } } } int main() { init(); solve(); return 0; }
- 
  1@ 2021-08-21 21:05:29#include<bits/stdc++.h> using namespace std; int n,sum[100010],q[100010],h[100010]; struct node{ int s; int a; }v[100010]; bool cmp(node x,node y){return x.a>y.a;} int main() { cin>>n; for(int i=1;i<=n;i++) cin>>v[i].s; for(int i=1;i<=n;i++) cin>>v[i].a; sort(v+1,v+1+n,cmp); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+v[i].a; for(int i=1;i<=n;i++) q[i]=max(q[i-1],2*v[i].s); for(int i=n;i>=1;i--) h[i]=max(h[i+1],2*v[i].s+v[i].a); for(int i=1;i<=n;i++) cout<<max(sum[i]+q[i],sum[i-1]+h[i])<<"\n"; return 0; }
- 
  1@ 2020-11-11 08:57:30#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <deque> #include <queue> using namespace std; namespace dts { class node { public: int num,s,a; }; class cmp1 { public: int operator() (node a,node b) { return a.a+(a.s<<1)<b.a+(b.s<<1); } }; class cmp2 { public: int operator() (node a,node b) { return a.a<b.a; } }; priority_queue<node,deque<node>,cmp1> h1; priority_queue<node,deque<node>,cmp2> h2; int n; vector<node> rec; int cmp_rec(node a,node b) { return a.s<b.s; } void main() { scanf("%d",&n); rec.resize(n); for (int i=0;i<n;i++) scanf("%d",&rec[i].s); for (int i=0;i<n;i++) scanf("%d",&rec[i].a); sort(&rec[0],&rec[n],cmp_rec); for (int i=0;i<n;i++) rec[i].num=i; for (int i=0;i<n;i++) h1.push(rec[i]); for (int i=0,pos=0,ans=0;!h1.empty()||!h2.empty();) { while (!h1.empty()) if (h1.top().num<i) h1.pop(); else break; if (h1.empty()) { while (!h2.empty()) { ans+=h2.top().a; h2.pop(); printf("%d\n",ans); } break; } if (h2.empty()) { choose_h1: node now=h1.top(); ans+=((now.s-pos)<<1)+now.a; pos=now.s; h1.pop(); for (;i<=now.num-1;i++) h2.push(rec[i]); i=now.num+1; printf("%d\n",ans); continue; } node n1=h1.top(),n2=h2.top(); if (n1.a+((n1.s-pos)<<1)>n2.a) goto choose_h1; else { ans+=h2.top().a; h2.pop(); printf("%d\n",ans); } } } } int main() { dts::main(); }
- 
  1@ 2018-11-08 18:52:43rkbudlo大神的天才思路 
 你们写的都好多#include<bits/stdc++.h> using namespace std; int Maxs[100005],Max[100005],sum[100005],n; struct tzg{int s,x;}a[100005]; bool cmp(tzg x,tzg y){return x.x>y.x;} int max(int x,int y){return x>y?x:y;} int main(){ scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%d",&a[i].s); for(int i=1;i<=n;++i)scanf("%d",&a[i].x); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;++i)sum[i]=sum[i-1]+a[i].x; for(int i=1;i<=n;++i)Maxs[i]=max(Maxs[i-1],a[i].s); for(int i=n;i>=1;--i)Max[i]=max(Max[i+1],a[i].s*2+a[i].x); for(int i=1;i<=n;++i)printf("%d\n",max(sum[i-1]+Max[i],sum[i]+Maxs[i]*2)); return 0; }
- 
  1@ 2016-11-09 15:42:37用堆做的,程序在我校的标准数据中是通过的,然而vj不知为啥不过,求指点 
 编译成功Free Pascal Compiler version 3.0.0 [2015/11/16] for i386 
 Copyright (c) 1993-2015 by Florian Klaempfl and others
 Target OS: Win32 for i386
 Compiling foo.pas
 foo.pas(44,32) Warning: range check error while evaluating constants (-1 must be between 0 and 4294967295)
 foo.pas(4,10) Note: Local variable "tmax" not used
 Linking foo.exe
 72 lines compiled, 0.0 sec, 28240 bytes code, 1268 bytes data
 1 warning(s) issued
 1 note(s) issued测试数据 #0: Accepted, time = 0 ms, mem = 3940 KiB, score = 10 测试数据 #1: WrongAnswer, time = 0 ms, mem = 3940 KiB, score = 0 测试数据 #2: WrongAnswer, time = 0 ms, mem = 3940 KiB, score = 0 测试数据 #3: Accepted, time = 15 ms, mem = 3940 KiB, score = 10 测试数据 #4: WrongAnswer, time = 15 ms, mem = 3940 KiB, score = 0 测试数据 #5: Accepted, time = 0 ms, mem = 3936 KiB, score = 10 测试数据 #6: RuntimeError, time = 31 ms, mem = 3936 KiB, score = 0 测试数据 #7: RuntimeError, time = 31 ms, mem = 3940 KiB, score = 0 测试数据 #8: RuntimeError, time = 46 ms, mem = 3940 KiB, score = 0 测试数据 #9: RuntimeError, time = 31 ms, mem = 3940 KiB, score = 0 RuntimeError, time = 169 ms, mem = 3940 KiB, score = 30 
 代码
 ```pascal
 //const bind=array[0..200001] of longint;
 var //heap:bind;
 heap,jli,pl,ans:array[0..200001] of longint;
 i,j,len,tmax,ti,li,n:longint;procedure swap(var a,b:longint); 
 var t:longint;
 begin t:=a;a:=b;b:=t;end;procedure put(a:longint); 
 var i:longint;
 begin
 inc(len);
 heap[len]:=a;
 i:=len;
 while (heap[i]>heap[i>>1])and(i<>1) do begin
 swap(heap[i],heap[i>>1]);
 i:=i>>1;
 end;
 end;function get:longint; 
 var i,t:longint;
 begin
 get:=heap[1];
 heap[1]:=heap[len];
 heap[len]:=-1;
 dec(len);i:=1;
 if len=0 then exit;
 while true do begin
 t:=i<<1;
 if (heap[i]<heap[t])and(heap[t]>heap[t+1])and(heap[t]<>-1)then begin
 swap(heap[i],heap[t]);i:=t;end
 else if (heap[i]<heap[t+1])and(heap[t+1]<>-1)then begin
 swap(heap[i],heap[t+1]);i:=t+1;end
 else break;
 end;
 end;begin 
 //assign(input,'salesman.in'); assign(output,'salesman.out');
 //reset(input); rewrite(output);
 read(n);
 filldword(heap,length(heap),-1);
 //filldword(d2,length(d2),maxlongint);
 //le[0]:=0;
 for i:=1 to n do read(jli[i]);
 for i:=1 to n do read(pl[i]);
 //l1:=0;l2:=0;
 //ans[1]:=get(d2,l2,l1);
 ans[1]:=pl[n]+jli[n]<<1;
 li:=1;ti:=n;
 for j:=n-1 downto 1 do if pl[j]+jli[j]<<1>ans[1] then begin
 ans[1]:=pl[j]+jli[j]<<1;ti:=j;
 end;
 for i:=1 to ti-1 do put(pl[i]);
 li:=ti;
 //for j:=1 to len do write(heap[j],' ');writeln;
 writeln(ans[1]);for i:=2 to n do begin 
 //writeln('li=',li);
 ans[i]:=0;
 for j:=n downto li+1 do if pl[j]+(jli[j]-jli[li])<<1>ans[i] then begin
 ans[i]:=pl[j]+(jli[j]-jli[li])<<1;ti:=j;//writeln('le');
 end;
 for j:=li+1 to ti-1 do put(pl[i]);//if i=5 then writeln(ans[i]);
 if (heap[1]>ans[i]) then ans[i]:=get else li:=ti;
 //for j:=1 to 5 do write(heap[j],' ');writeln;
 inc(ans[i],ans[pred(i)]);writeln(ans[i]);
 end;
 //close(input); close(output);
 end.
 ```
- 
  0@ 2017-08-12 14:37:51大神们能帮我看看么??少了第一个输出 
 #include <iostream>
 #include <iomanip>
 #include <cstdlib>
 #include <cmath>
 #include <string>
 #include <algorithm>
 #include <queue>
 #include <set>
 #include <map>
 #include <stack>
 #include <vector>
 #include <list>
 #include <cstdio>
 #include <deque>
 #include <cstring>
 #include <stdlib.h>using namespace std; 
 int comp(int a,int b)
 {
 return a>b;
 }
 int main()
 {
 freopen("salesman.in","r",stdin);
 freopen("salesman.out","w",stdout);
 long n,tie[100000],pt[100000],sum[100000],pp[100000],s;
 cin>>n;
 for(int i=1;i<=n;++i)
 cin>>pt[i];
 for(int i=1;i<=n;++i)
 {
 cin>>tie[i];
 pt[i]=pt[i]*2+tie[i];
 }
 for(int i=2;i<=n;++i)
 {
 for(int l=1;l<=n;++l)
 pp[l]=tie[l];
 for(int k=i;k<=n;++k)
 {
 sort(pp+1,pp+k-1,comp);
 for(int j=1;j<=i-1;++j)
 s=s+pp[j];
 sum[k]=pt[k]+s;
 s=0;
 }
 sort(sum+i,sum+n,comp);
 cout<<sum[i]<<endl;
 memset(sum,0,sizeof(sum));
 }
 return 0;
 }
- 
  0@ 2017-08-04 13:00:50Var i,j:longint; max,num,n:int64; a,b:array[1..1000000]of int64; Procedure kp(l,r:int64); Var i,j,t,mid:int64; Begin i:=l; j:=r; mid:=b[(i+j) div 2]; repeat while b[i]>mid do inc(i); while b[j]<mid do dec(j); if i<=j then begin t:=b[i]; b[i]:=b[j]; b[j]:=t; t:=a[i]; a[i]:=a[j]; a[j]:=t; inc(i); dec(j); end; until i>j; if i<r then kp(i,r); if l<j then kp(l,j); End; Begin readln(n); for i:=1 to n-1 do read(a[i]); readln(a[n]); for i:=1 to n-1 do read(b[i]); readln(b[n]); max:=-1; for i:=1 to n do if max<a[i]*2+b[i] then begin j:=i; max:=a[i]*2+b[i]; end; b[j]:=0; writeln(max); num:=max-a[j]*2; kp(1,n); i:=0; while i<n-1 do begin inc(i); num:=num+b[i]; if num+a[i]*2>max+b[i] then max:=num+a[i]*2 else if num+a[i]*2<=max+b[i] then max:=max+b[i]; writeln(max); end; readln; End.不科学啊。。这个放到洛谷是全对的啊、 
 #1
 AC
 0ms/9269kB#2 
 AC
 52ms/9269kB#3 
 AC
 0ms/9269kB#4 
 AC
 0ms/9269kB#5 
 AC
 0ms/9269kB#6 
 AC
 0ms/9269kB#7 
 AC
 0ms/9269kB
 #8
 AC
 55ms/9269kB#9 
 AC
 51ms/9269kB#10 
 AC
 61ms/9269kB
 在这里就不对。。。。vijos测试数据有问题》???
- 
  0@ 2016-12-21 22:02:12var a,s,p,sum,b,c,m1,m2,f:array[0..100000] of longint; 
 n,i,j:longint;
 function max(x,y:longint):longint;
 begin
 if x>y then exit(x) else exit(y);
 end;
 procedure qsort(l,r:longint);
 var i,j,k,t,t1,t2:longint;
 begin
 i:=l; j:=r; k:=(i+j) div 2;
 t:=a[k]; a[k]:=a[i];
 t1:=p[k]; p[k]:=p[i];
 while i<j do
 begin
 while (i<j)and(a[j]<t) do dec(j);
 if i<j then
 begin
 a[i]:=a[j];
 p[i]:=p[j];
 inc(i);
 end;
 while (i<j)and(a[i]>t) do inc(i);
 if i<j then
 begin
 a[j]:=a[i];
 p[j]:=p[i];
 dec(j);
 end;
 end;
 p[i]:=t1;
 if i-1>l then qsort(l,i-1);
 if i+1<r then qsort(i+1,r);
 end;
 begin
 assign(input,'salesman.in');
 assign(output,'salesman.out');
 reset(input);
 rewrite(output);
 readln(n);
 for i:=1 to n do read(s[i]);
 readln;
 for i:=1 to n do
 begin
 read(a[i]);
 p[i]:=i;
 end;
 b:=a;
 qsort(1,n);
 a:=b;
 sum[1]:=a[p[1]];
 m1[1]:=p[1];
 for i:=2 to n do
 begin
 sum[i]:=sum[i-1]+a[p[i]];
 if s[m1[i-1]]>s[p[i]] then m1[i]:=m1[i-1]
 else m1[i]:=p[i];
 end;
 m2[n]:=p[n];
 for i:=n-1 downto 1 do
 begin
 if 2*s[m2[i+1]]+a[m2[i+1]]>2*s[p[i]]+a[p[i]] then m2[i]:=m2[i+1]
 else m2[i]:=p[i];
 end;
 for i:=1 to n do
 writeln(max(sum[i-1]+a[m2[i]]+max(s[m1[i-1]],s[m2[i]])*2,sum[i]+s[m1[i]]*2));
 close(input);
 close(output);
 end.
- 
  0@ 2016-11-18 18:54:04贪心 
 #include<cstdio>
 #include<iostream>
 #include<algorithm>
 using namespace std;
 struct data{
 long long dis;
 long long tired;
 };
 data info[100010];
 long long g[100010]={0},h[100010]={0},x[100010]={0},f[100010]={0};
 bool cmp(data a,data b){
 return a.tired<b.tired;
 }
 int main(){
 int n;
 scanf("%d",&n);
 for(int i=1;i<=n;i++) scanf("%d",&info[i].dis);
 for(int i=1;i<=n;i++) scanf("%d",&info[i].tired);
 sort(info,info+n+1,cmp);
 for(int i=1;i<=n;i++) g[i]=max(info[i].dis*2+info[i].tired,g[i-1]);
 h[n]=2*info[n].dis;
 for(int i=n;i>=1;i--) h[i]=max(h[i+1],info[i].dis*2);
 for(int i=n;i>=1;i--) x[i]=x[i+1]+info[i].tired;
 for(int i=n;i>=1;i--){
 f[i]=x[i]+h[i];
 f[i]=max(f[i],x[i+1]+g[i-1]);
 }
 for(int i=n;i>=1;i--) printf("%d\n",f[i]);
 return 0;
 }
- 
  0@ 2016-11-14 12:31:28树状数组? 
- 
  0@ 2016-11-03 20:05:17http://blog.csdn.net/u013598409/article/details/53025285 
 这道题的正解是堆。
 膜拜yww大神。
 ```c++
 #include <cstdio>
 #include <cctype>
 #include <queue>
 using namespace std;#define rep(i,a,b) for (int i=(a);i<=(b);i++) #define x first 
 #define y second
 #define mp make_pairtypedef pair<int,int> PII; const int N=131072; int n; 
 int s[N],a[N];int cur,vis[N]; 
 priority_queue<PII> qs,qb;
 int res;inline int rd(void) 
 {
 int x=0,f=1; char c=getchar();
 for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
 for (;isdigit(c);c=getchar()) x=x*10+c-'0';
 return x*f;
 }int main(void) 
 {
 // freopen("a.in","r",stdin);
 // freopen("a.out","w",stdout);n=rd(); 
 rep(i,1,n) s[i]=rd();
 rep(i,1,n) a[i]=rd();rep(i,1,n) 
 qb.push(mp(2*s[i]+a[i],i));PII t1,t2; int e1,e2,cs; 
 rep(i,1,n)
 {
 while (!qs.empty())
 {
 t1=qs.top();
 if (vis[t1.y])
 qs.pop();
 else break;
 }
 while (!qb.empty())
 {
 t2=qb.top();
 if (t2.y<cur||vis[t2.y])
 qb.pop();
 else break;
 }e1=(!qs.empty()); 
 e2=(!qb.empty());
 if (!e1&&e2)
 cs=2;
 else if (e1&&!e2)
 cs=1;
 else if (e1&&e2)
 {
 t1=qs.top(),t2=qb.top();
 if (t2.x-2*s[cur]>=t1.x)
 cs=2;
 else cs=1;
 }if (cs==1) 
 {
 t1=qs.top(); qs.pop();
 vis[t1.y]=1;
 res+=t1.x;
 }
 else if (cs==2)
 {
 t2=qb.top(); qb.pop();
 vis[t2.y]=1;
 rep(j,cur+1,t2.y)
 if (!vis[j])
 qs.push(mp(a[j],j));
 res+=(t2.x-2*s[cur]);
 cur=t2.y;
 }printf("%d\n",res); 
 }return 0; 
 }
 ```
- 
  0@ 2016-10-14 21:05:27单调队列+优先队列 
- 
  0@ 2016-10-06 07:50:48只需要两个堆 
 
 #include<cstdio>
 #include<cstring>
 #include<cstdlib>
 #include<algorithm>
 #include<ctime>
 #include<queue>
 using namespace std;
 typedef long long ll;
 int s[100010];
 int a[100010];
 int b[100010];
 typedef pair<int,int> pa;
 priority_queue<pa> q1,q2;
 int main()
 {
 memset(b,0,sizeof(b));
 int n;
 int i;
 scanf("%d",&n);
 for(i=1;i<=n;i++)
 scanf("%d",&s[i]);
 for(i=1;i<=n;i++)
 scanf("%d",&a[i]);
 int x=0;
 for(i=1;i<=n;i++)
 q2.push(make_pair(a[i]+2*s[i],i));
 int ans=0;
 for(i=1;i<=n;i++)
 {
 while(!q1.empty()&&b[q1.top().second])
 q1.pop();
 while(!q2.empty()&&(b[q2.top().second]||q2.top().second<=x))
 q2.pop();
 int t1=-1,t2=-1;
 if(!q1.empty())
 t1=q1.top().first;
 if(!q2.empty())
 t2=q2.top().first-2*s[x];
 if(t1>t2)
 {
 b[q1.top().second]=1;
 ans+=t1;
 q1.pop();
 }
 else
 {
 b[q2.top().second]=1;
 ans+=t2;
 while(x<q2.top().second)
 {
 x++;
 q1.push(make_pair(a[x],x));
 }
 q2.pop();
 }
 printf("%d\n",ans);
 }
 return 0;
 }
 
- 
  0@ 2016-08-06 10:53:10不错的好题! 
 用构造反证法可以证明,每一次最大都是在前一次基础上增加一个;或者说,每一次最大都是在后一次基础上减少一个。不难发现后一种思路适合使用线段树求解。
 一个棘手的问题是:**如果改变的是最远点,走路疲劳会减少**。不妨增加一个特判,每次把最远的点和次远的点找到,把最远点的疲劳度加上最远点到次远点距离的二倍作为增量。
 那么问题就转化为如何找到最远点和次远点。不难发现最远点和次远点都是单调的,因此可以用摊还O(1)的时间找到他们。这样问题就解决了。总的时间复杂度为O(nlgn+n)=O(nlgn)。
 - 测试数据 #0: Accepted, time = 0 ms, mem = 9164 KiB, score = 10
 - 测试数据 #1: Accepted, time = 0 ms, mem = 9164 KiB, score = 10
 - 测试数据 #2: Accepted, time = 15 ms, mem = 9164 KiB, score = 10
 - 测试数据 #3: Accepted, time = 0 ms, mem = 9160 KiB, score = 10
 - 测试数据 #4: Accepted, time = 0 ms, mem = 9164 KiB, score = 10
 - 测试数据 #5: Accepted, time = 15 ms, mem = 9164 KiB, score = 10
 - 测试数据 #6: Accepted, time = 125 ms, mem = 9164 KiB, score = 10
 - 测试数据 #7: Accepted, time = 93 ms, mem = 9164 KiB, score = 10
 - 测试数据 #8: Accepted, time = 125 ms, mem = 9164 KiB, score = 10
 - 测试数据 #9: Accepted, time = 125 ms, mem = 9168 KiB, score = 10Accepted, time = 498 ms, mem = 9168 KiB, score = 100 
 ```c++
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 using namespace std;class zkw { 
 long long arr[400005], max_pos[400005];
 int n;
 public:
 zkw()
 {
 memset(arr, 127, sizeof arr);
 n = 1<<17;
 for (int i = n; i < n+n; i++)
 max_pos[i] = i-n+1;
 }
 inline int pos(int i)
 {
 return i + n - 1;
 }
 inline void fix(int i)
 {
 arr[i] = min(arr[i<<1], arr[(i<<1)+1]);
 max_pos[i] = arr[i] == arr[i<<1] ? max_pos[i<<1] : max_pos[(i<<1)+1];
 if (i > 1)
 fix(i >> 1);
 }
 inline void modify(int i, int j)
 {
 int t = pos(i);
 arr[t] = j;
 fix(t >> 1);
 }
 inline long long top()
 {
 return arr[1];
 }
 inline int top_pos()
 {
 return max_pos[1];
 }
 inline long long in(int i)
 {
 return arr[pos(i)];
 }
 }zkwheap;long long n; 
 long long len[100005], A[100005];
 long long ans[100005];
 int main()
 {
 scanf("%d", &n);
 for (int i = 1; i <= n; i++)
 scanf("%d", &len[i]);
 A[0] = 0;
 for (int i = 1; i <= n; i++) {
 scanf("%d", &A[i]);
 zkwheap.modify(i, A[i]);
 A[i] += A[i-1];
 }
 ans[n] = A[n]+len[n]+len[n];
 int first = n, second = n-1;
 zkwheap.modify(n, zkwheap.in(n)+2*(len[n]-len[n-1]));
 for (int i = n-1; i >= 1; i--) {
 int tp = zkwheap.top_pos();
 long long val = zkwheap.top();
 ans[i] = ans[i+1] - val;
 zkwheap.modify(tp, 1000000000);
 if (second == tp) {
 while (zkwheap.in(second) >= 10000000)
 second--;
 zkwheap.modify(first, A[first]-A[first-1]+2*(len[first]-len[second]));
 }
 if (first == tp) {
 first = second;
 while (first == second || zkwheap.in(second) >= 10000000)
 second--;
 zkwheap.modify(first, zkwheap.in(first)+2*(len[first]-len[second]));
 }
 }
 for (int i = 1; i <= n; i++)
 printf("%d\n", ans[i]);
 return 0;
 }
- 
  0@ 2016-07-14 08:58:44#include<iostream> 
 #include<cstdio>
 #include<algorithm>
 #include<cstring>
 #include<queue>
 using namespace std;
 const int maxn=100000+2;
 int ss[maxn],aa[maxn];
 bool idx[maxn];
 struct hh{
 int s,h,xu;
 friend bool operator>(hh a,hh b) {if (a.h!=b.h) return a.h<b.h;else return a.s<b.s;}
 hh(int a=0,int b=0,int c=0){s=a;h=b;xu=c;}
 };
 int main(){
 // freopen("salesman.txt","r",stdin);
 // freopen("my.txt","w",stdout);
 memset(idx,0,sizeof(idx));
 int n;
 cin>>n;
 priority_queue<int,vector<int>,less<int > >q1;
 priority_queue<hh,vector<hh>,greater<hh> >q2;
 for(int i=0;i<n;i++) scanf("%d",&ss[i]);
 for(int i=0;i<n;i++){
 scanf("%d",&aa[i]);
 q2.push(hh(ss[i],ss[i]*2+aa[i],i));
 }
 hh q2m=q2.top();q2.pop();
 int m=q2m.h,c=q2m.s,x=q2m.xu,x0=0;idx[x]=1;
 for(int i=0;i<n;i++){
 printf("%d\n",m);
 if(i==n-1) break;
 int q1m=0;q2m.h=0;
 for(int i=x0;i<x;i++) if(!idx[i]) q1.push(aa[i]);
 x0=x+1;q1m=q1.top();
 while(!q2.empty()){
 q2m=q2.top();
 if(q2m.xu>x) break;
 q2.pop();
 }
 q2m.h-=c*2;
 if(q2m.h>q1m) {
 q2.pop();m+=q2m.h;c=q2m.s;x=q2m.xu;idx[x]=1;/*printf("%d->%d**\n",q2m.xu,q2m.h);*/
 }
 else {
 q1.pop();m+=q1m;/*printf("%d->**\n",q1m);*/
 }
 }
 return 0;
 }
- 
  0@ 2016-07-12 16:07:58Free Pascal Compiler version 3.0.0 [2015/11/16] for i386 
 Copyright (c) 1993-2015 by Florian Klaempfl and others
 Target OS: Win32 for i386
 Compiling foo.pas
 foo.pas(31,26) Warning: Variable "max" does not seem to be initialized
 Linking foo.exe
 51 lines compiled, 0.1 sec, 28240 bytes code, 1268 bytes data
 1 warning(s) issued
 测试数据 #0: Accepted, time = 0 ms, mem = 1588 KiB, score = 10
 测试数据 #1: WrongAnswer, time = 0 ms, mem = 1584 KiB, score = 0
 测试数据 #2: WrongAnswer, time = 0 ms, mem = 1584 KiB, score = 0
 测试数据 #3: WrongAnswer, time = 0 ms, mem = 1584 KiB, score = 0
 测试数据 #4: WrongAnswer, time = 15 ms, mem = 1588 KiB, score = 0
 测试数据 #5: WrongAnswer, time = 0 ms, mem = 1580 KiB, score = 0
 测试数据 #6: WrongAnswer, time = 406 ms, mem = 1584 KiB, score = 0
 测试数据 #7: Accepted, time = 203 ms, mem = 1584 KiB, score = 10
 测试数据 #8: WrongAnswer, time = 250 ms, mem = 1592 KiB, score = 0
 测试数据 #9: WrongAnswer, time = 328 ms, mem = 1580 KiB, score = 0
 WrongAnswer, time = 1202 ms, mem = 1592 KiB, score = 20
 呵呵!在noip标准数据上过的代码~
- 
  0@ 2016-07-09 13:34:16#include<iostream> 
 #include<cstring>
 #include<cstdio>
 using namespace std;
 long long m,q[100011],w[100011],a[100011],l,s,ans;
 long long cut()
 {
 int m=a[1],x=1,y=2;
 a[1]=a[s];
 s--;
 while(y<=s&&(a[x]<a[y]||a[x]<a[y+1]))
 {
 if(y<s&&a[y]<a[y+1])y++;
 int t=a[x];
 a[x]=a[y];
 a[y]=t;
 x=y;
 y=2*y;
 }
 return m;
 }
 void charu(int k)
 {
 int x=k,si=++s;
 while(k>a[si/2]&&si>1)
 {
 a[si]=a[si/2];
 si/=2;
 }
 a[si]=x;
 }
 int main()
 {
 scanf("%lld",&m);
 for(int i=1;i<=m;i++)
 scanf("%lld",&q[i]);
 for(int i=1;i<=m;i++)
 scanf("%lld",&w[i]);
 long long b=0,c=0,xc=-1;
 for(int i=1;i<=m;i++)
 {
 for(int j=l+1;j<=m;j++)
 {
 int k=(q[j]-l)*2+w[j];
 if(k>c){xc=j;c=k;}
 }
 if(c>b)
 {
 ans+=c;
 for(int j=l+1;j<xc;j++)
 charu(w[j]);
 l=xc;
 c=0;
 }
 else
 ans+=b;
 b=cut();
 printf("%lld\n",ans);
 }
 return 0;
 }
- 
  0@ 2016-06-25 22:01:09//刚刚那个不规范 求指点 
 #define _CRT_SECURE_NO_WARNINGS
 #include<stdio.h>
 long zhuhu[100001][2];
 long meigezhuhudezhi[100001], linshizongzhi[100001], jieguo[100001];long main(void) { long max, i, j; 
 scanf("%ld", &max);
 for (i = 0;i < max;i++)
 scanf("%ld", &zhuhu[i][0]);//记录距离
 for (i = 0;i < max;i++)
 scanf("%ld", &zhuhu[i][1]);//记录产品疲劳值
 long dangqianzuileizhuhu = 0;
 for (i = 0;i < max;i++) {
 linshizongzhi[i] = 2 * zhuhu[i][0] + zhuhu[i][1];
 if (linshizongzhi[dangqianzuileizhuhu] < linshizongzhi[i])
 dangqianzuileizhuhu = i;} 
 jieguo[0] = linshizongzhi[dangqianzuileizhuhu];
 long temp;
 for (i = 0;i < max;i++)
 {
 /* temp = zhuhu[dangqianzuileizhuhu][0] - zhuhu[i][0];
 if (temp < 0)
 linshizongzhi[i]=2*abs(zhuhu[dangqianzuileizhuhu][0] - zhuhu[i][0]);
 else linshizongzhi[i] -= zhuhu[i][0];*/if (i < dangqianzuileizhuhu) 
 linshizongzhi[i] -= 2 * zhuhu[i][0];
 else
 linshizongzhi[i] += 2 * (zhuhu[i][0] - zhuhu[dangqianzuileizhuhu][0]) - 2 * zhuhu[i][0];
 }
 linshizongzhi[dangqianzuileizhuhu] = 0;
 long l = 1;
 for (i = 0;i < max;i++) {
 temp = 0;
 for (j = 0;j < max;j++)
 if (linshizongzhi[temp] < linshizongzhi[j])
 temp = j;
 jieguo[l] = jieguo[l - 1] + linshizongzhi[temp];
 linshizongzhi[temp] = 0;
 l++;
 }
 for (i = 0;i < max;i++) {
 printf("%ld\n", jieguo[i]);
 }
 // system("pause");
 }
信息
- ID
- 1977
- 难度
- 8
- 分类
- (无)
- 标签
- 递交数
- 2273
- 已通过
- 271
- 通过率
- 12%
- 被复制
- 17
- 上传者