B:
#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=4e5+5;
struct node{
ll w,s,c;
}a[maxn];
bool cmp(node a,node b){
return a.c>b.c;
}
int main(){
ll n;cin>>n;
ll sum=0;
for(ll i=1;i<=n;i++){
cin>>a[i].w>>a[i].s;
a[i].c=a[i].w+a[i].s;
sum+=a[i].w;
}
sort(a+1,a+1+n,cmp);
ll maxx=-INF;
for(ll i=1;i<=n;i++){
maxx=max(maxx,sum-(a[i].c));
sum-=a[i].w;
}
cout<<maxx<<endl;
}
C:codeforces-1077D
Emmmm,这里我运用了优先队列,不同于其他题解的二分,大概思路就是记录每个数的次数,然后存进优先队列里,所以每次top都是数量最多的,那既然是数量最多的,那肯定是要取的,然后就把它塞进ans的数组里面。但是有可能一个数会多次取(当他的次数足够大的时候),所以这时候我们要记录他已经用过的次数af[u],af[u]从1~该数本身,然后原次数除以af[u],就是当前数字的当前次数。因为是优先队列,所以不必担心,每次都是最多的放前面,直到我们满足k个的时候,自然而然会跳出循环啦。
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=4e5+5;
ll n,k,a[maxn],f[maxn],af[maxn];
priority_queue<pair<int,int> > p;
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
f[a[i]]++;
}
for(int i=1;i<=200000;i++){
if(f[i]) p.push({f[i],i});
}
vector<int> ans;
while(ans.size()<k){
pair<int,int> q=p.top();
p.pop();
int u=q.second;
ans.push_back(u);
af[u]++;
p.push({f[u]/(af[u]+1),u});
}
for(int i=0;i<k;i++){
cout<<ans[i]<<" ";
}
}
I :codeforces-1221D
这个题要用dp,一开始没想出来是dp,其实每个数字最多+2位就行了,所以状态转移方程是:
dp[i][k]=min(dp[i][k],dp[i-1][j]+k*b[i])
每次比较i的位置和i-1的位置,通过dp构造得出最优解,然后遍历n的+0,+1,+2三种情况取最小即可。
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int maxm=3e5+5;
const int inf=1e18;
int d[maxm][3];
int a[maxm],b[maxm];
int n;
signed main(){
ios::sync_with_stdio(0);
int T;
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
}
for(int i=1;i<=n;i++){//init
for(int j=0;j<3;j++){
d[i][j]=inf;
}
}
d[1][0]=0;
d[1][1]=b[1];
d[1][2]=2*b[1];
for(int i=2;i<=n;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
if(a[i-1]+j!=a[i]+k){
d[i][k]=min(d[i][k],d[i-1][j]+k*b[i]);
}
}
}
}
int ans=min(min(d[n][0],d[n][1]),d[n][2]);
cout<<ans<<endl;
}
return 0;
}