http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1689
题意:
题意:
枚举终点,这样就确定路上的花费,接下来只需要计算进店的花费,用三个优先队列维护,q1存储必须要进的ci为1的k个店的最小进店花费,q2存储除了q1中的店之外还能进的店,q3存储暂时不能进的店。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 typedef pair<int,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const int maxn = 100000+5; 16 17 int n, k, t; 18 int a[maxn],b[maxn],c[maxn]; 19 20 priority_queue<int> q1,q2,q3; 21 22 int main() 23 { 24 //freopen("in.txt","r",stdin); 25 while(~scanf("%d%d%d",&n,&t,&k)) 26 { 27 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 28 for(int i=1;i<=n;i++) scanf("%d",&b[i]); 29 for(int i=1;i<=n;i++) scanf("%d",&c[i]); 30 31 ll sum1=0,sum2=0; 32 int ans=-1; 33 for(int i=1;i<=n;i++) 34 { 35 if(c[i]) 36 { 37 q1.push(b[i]); 38 sum1+=b[i]; 39 } 40 else 41 { 42 q2.push(b[i]); 43 sum2+=b[i]; 44 } 45 if(q1.size()>k) 46 { 47 int tmp = q1.top(); 48 sum1-=tmp; 49 sum2+=tmp; 50 q2.push(tmp); 51 q1.pop(); 52 } 53 if(q1.size()<k) continue; 54 if(sum1+a[i]>t) continue; 55 ll left=t-sum1-a[i]; 56 while(!q3.empty() && !q2.empty() && -q3.top()<q2.top()) //q2的最大花费和q3的最小花费交换 57 { 58 int tmp2=q2.top(); 59 int tmp3=q3.top(); 60 q2.pop(); 61 q3.pop(); 62 sum2-=tmp2; 63 sum2-=tmp3; 64 q2.push(-tmp3); 65 q3.push(-tmp2); 66 } 67 while(!q2.empty() && sum2>left) //如果q2里的进店花费超过了限制,则需要去掉一些 68 { 69 int tmp=q2.top(); 70 q2.pop(); 71 sum2-=tmp; 72 q3.push(-tmp); 73 } 74 while (!q3.empty() && left >= sum2 - q3.top()) //q2加上q3里较小的还是满足的 75 { 76 q2.push(-q3.top()); 77 sum2 -= q3.top(); 78 q3.pop(); 79 } 80 if(sum1+sum2+a[i]<=t && k+(int)q2.size()>ans) 81 ans=k+(int)q2.size(); 82 } 83 printf("%d ",ans); 84 } 85 return 0; 86 }