长安大学寒假第二次排位赛部分题解

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;
}

发布了90 篇原创文章 · 获赞 6 · 访问量 5015

猜你喜欢

转载自blog.csdn.net/Rainfoo/article/details/104181623