概括起来就是前m个里一定有n个的问题,可以追溯到很经典的一个题:一辆车经过几个加油站,每个加油站有价格不同的一定量油,开车要消耗油,问至少多少钱到终点。做法就是先假装不加,油不够了再往前面找最便宜的加油站加,用一个优先队列维护即可。这类题的难点在于抽象出这个模型往往隐藏得很深,要看出来才行。
http://codeforces.com/problemset/problem/3/D
#include <bits/stdc++.h>
using namespace std;
char str[50500];
int main()
{
scanf("%s", str+1);
int l=strlen(str+1);
if(l%2!=0){
printf("-1\n");
return 0;
}
int a, b;
long long ans=0;
int sta=0;
if(str[1]==')'){
printf("-1\n");
return 0;
}
else if(str[1]=='?'){
scanf("%d%d", &a, &b);
ans+=a;
str[1]='(';
}
priority_queue<pair<int, int> >pq;
for(int i=1;i<l/2;i++){
if(str[2*i]==')'){
sta--;
}
else if(str[2*i]=='('){
sta++;
}
else {
scanf("%d%d", &a, &b);
ans+=b;
pq.push(make_pair(b-a, 2*i));
str[2*i]=')';
sta--;
}
if(str[2*i+1]==')'){
sta--;
}
else if(str[2*i+1]=='('){
sta++;
}
else {
scanf("%d%d", &a, &b);
ans+=b;
pq.push(make_pair(b-a, 2*i+1));
str[2*i+1]=')';
sta--;
}
while(sta<0){
if(pq.empty()){
printf("-1\n");
return 0;
}
pair<int, int>tmp=pq.top();
pq.pop();
sta+=2;
ans-=tmp.first;
str[tmp.second]='(';
}
}
if(sta>0){
printf("-1\n");
return 0;
}
if(str[l]=='('){
printf("-1\n");
return 0;
}
else if(str[l]=='?'){
scanf("%d%d", &a, &b);
ans+=b;
str[l]=')';
}
printf("%lld\n%s\n", ans, str+1);
}
http://codeforces.com/gym/100956/attachments D
#include <bits/stdc++.h>
using namespace std;
int n;
int a[105000];
int b[105000];
int c[105000];
bool cmp(int x, int y){
if(a[x]!=a[y])return a[x]>a[y];
else return b[x]>b[y];
}
int main()
{
scanf("%d", &n);
for(int i=1;i<=n;i++)scanf("%d", &a[i]);
for(int i=1;i<=n;i++)scanf("%d", &b[i]);
for(int i=1;i<=n;i++)c[i]=i;
sort(c+1, c+1+n, cmp);
priority_queue<int, vector<int>, greater<int> >pq;
long long ans=0;
for(int i=1;i<=n/2;i++){
pq.push(b[c[2*i]]);
if(2*i+1<=n)pq.push(b[c[2*i+1]]);
else pq.push(0);
pq.pop();
}
while(!pq.empty()){
ans+=pq.top();
pq.pop();
}
printf("%lld\n", ans);
}
http://codeforces.com/problemset/problem/767/E
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m;
ll c[105000];
ll w[105000];
ll s[105000];
int main()
{
scanf("%lld%lld", &n, &m);
for(int i=1;i<=n;i++)scanf("%lld", &c[i]);
for(int i=1;i<=n;i++)scanf("%lld", &w[i]);
ll dis=0;
priority_queue<pair<ll, ll>, vector<pair<ll, ll> >, greater<pair<ll, ll> > >pq;
for(int i=1;i<=n;i++){
if(c[i]%100==0){
s[i]=c[i]/100;
}
else{
s[i]=c[i]/100;
m-=(c[i]-s[i]*100);
pq.push(make_pair(w[i]*(100-c[i]+s[i]*100),i));
if(m<0){
m+=100;
pair<ll, ll> tmp=pq.top();
pq.pop();
dis+=tmp.first;
s[tmp.second]++;
}
}
}
printf("%lld\n", dis);
for(int i=1;i<=n;i++){
printf("%lld ", s[i]);
if(s[i]*100<c[i])printf("%lld\n", c[i]-s[i]*100);
else printf("0\n");
}
}