Codeforces Round #642 (Div. 3) A~E

思维,一个数0,两个数m,三个数以上,先放0 m 0,结果是2*m


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const int N=1e5+10;
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		int n,m;
		cin>>n>>m;
		if(n==1)
			cout<<0<<endl;
		else if(n==2)
			cout<<m<<endl;
		else
			cout<<2*m<<endl;
	}
	return 0;
}

排序,然后贪心k次,如果当前A中最小的比b中最大的大,就交换


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const int N=50;
int a[N];
int b[N];
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		int n,k;
		cin>>n>>k;
		rep(i,0,n)
			cin>>a[i];
		rep(i,0,n)
			cin>>b[i];
		sort(a,a+n);
		sort(b,b+n);
		for(int i=0; i<k; i++){
			if(a[i]<b[n-i-1])
				a[i]=b[n-i-1];
		}
		int ans=0;
		rep(i,0,n)
			ans+=a[i];
		cout<<ans<<endl;
	}
	return 0;
}

递推,首先可以发现,挪到最中间那个格子,次数最小。然后是个递推


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const int N=250010;
LL dp[N];
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	dp[0]=0;
	for(LL i=1; i<N; i++)
		dp[i]=dp[i-1]+(i-1)*(i-1);
	while(_--){
		int n;
		cin>>n;
		cout<<8*dp[(n+1)/2]<<endl;

	}
	return 0;
}

优先队列真的香,直接模拟


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const int N=2e5+10;
int ans[N];
struct Cmp
{
	bool operator ()(PII& a, PII& b){
		if(a.se-a.fi==b.se-b.fi)//小的前面
			return a.fi>b.fi;
		else
			return (a.se-a.fi)<(b.se-b.fi);
	}
};

priority_queue<PII, vector<PII>,Cmp> pq;
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	int mid=0;
	while(_--){
		int n;
		cin>>n;
		pq.push(make_pair(1,n));
		rep(i,1,n+1){
			PII temp=pq.top();
			pq.pop();
			if((temp.se-temp.fi+1)&1) //奇数
				mid=(temp.fi+temp.se)/2;
			else
				mid=(temp.fi+temp.se-1)/2;
			ans[mid]=i;
			if(mid>temp.fi)
				pq.push(make_pair(temp.fi,mid-1));
			if(mid<temp.se)
				pq.push(make_pair(mid+1,temp.se));
		}
		rep(i,1,n+1)
			cout<<ans[i]<<" ";
		cout<<endl;
	}
	return 0;
}

做的时候想到了是分组来做,但是没想到每一组具体怎么做
其实就是基于一个简单事实,对于一组,如果在i位置上要能是1
那么它前面的肯定要么全是0,要么已经安置好了一段连续的1,于是直接
分组dp,计算答案哪儿还不是特别想明白,还得思考


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<int,int>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(int i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const int N=1e6+10;
string a;
int solve(string& s){
	int cnt=count(s.begin(),s.end(),'1');
	int n=s.length();
	vector<int> res(n);
	int prefix=0;
	int ans=cnt;
	rep(i,0,n){
		int cur=s[i]-'0';
		prefix += cur;
		//dp[i]=min(dp[i-1],prefix[i-1]) + s[i]!='1'
		res[i]='1'-s[i];
		if(i>0)
			res[i] += min(prefix-s[i]+'0',res[i-1]);
		ans = min(ans,res[i]+cnt-prefix);

	}
	return ans;
}
int main(int argc, char const *argv[])
{
	// #define DEBUG
	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	int _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		int n,k;
		cin>>n>>k;
		cin>>a;
		int cnt=count(all(a),'1');
		vector<string> part(k,"");
		rep(i,0,n)
			part[i%k] += a[i];
		int ans= INT_MAX;
		for(auto &s:part){
			ans = min(ans,solve(s)+cnt-count(all(s),'1'));
		}
		cout<<ans<<endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Crossea/p/12895171.html