第二篇博客 codeforces round #642 div3

D. Constructing the Array

题目链接:点击查看
题目描述:

给一个n个0的数组,每次都去寻找最左边的最长连续0子段的中间位置进行赋值。

题目分析:

可以使用优先队列进行解决,每次都是将node(l,r)添加进去,每次取出来的都是连续0长度最长或者是最左边的段。

代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int a[200005];
struct node{
	int l;
	int r;
	node(int x,int y){
		l=x;
		r=y;
	}
	bool operator < (const node & temp)const{
		if(r-l==temp.r-temp.l){
			return temp.l < l;//相等长度,左边优先 
		}
		return temp.r-temp.l>r-l;
	}
};
priority_queue<node> q;
void bfs(){
	int cnt=0;
	q.push(node(1,n));
	while(!q.empty()){
		node temp = q.top();
		q.pop();
		if(temp.l>temp.r)continue;
		int mid = (temp.l+temp.r)>>1;
		a[mid]=++cnt;
		q.push(node(temp.l,mid-1));
		q.push(node(mid+1,temp.r));
	}
}
int main()
{
	int t;
	cin >> t;
	while(t--){
		scanf("%d",&n);
		bfs();
		for(int i = 1; i <= n; ++i){
			printf("%d ",a[i]);
		}
		cout << endl;
	}
	return 0;
}

E. K-periodic Garland

题目链接:点击查看
题目描述:

给一个01字符串,每次操作改变一个字符状态,使得字符串中1的相邻距离为k,问最少操作数。

题目分析:

可以使用dp进行解决。

sum[i]:记录前i项中1的个数。

dp[i][0]表示前i项都正确,第i位为0时的最小操作次数。

dp[i][1]表示前i项都正确,第i位为1时的最小操作次数。

转移方程:

  • dp[i][0]=min(dp[i−1][0],dp[i−1][1])+(s[i]==‘1’)

当前记录第i项为0时的状态,那么此处为0对前面是否正确不影响,可以直接
从dp[i−1][0]或者dp[i−1][1]转移过来,如果s[i]==‘1’,那么操作数加1。

  • dp[i][1]=min(dp[i−k][1]+sum[i−1]−sum[i−k],sum[i−1])+(s[i]==‘0’)

当前记录第i项为1时的状态,如果前i−k项合法时,要使第i项为1时合法,需要我们使第i−k+1项到第i−1项都为0,第i项才能为1,这也就是为什么要记录前缀和1的个数。或者让前i-1项数都为0,这种情况是sum[i-1]。然后比较取小值。最后操作数会根据s[i]=='0’继续加1。

代码:
#include<bits/stdc++.h>
using namespace std;
int n,k;
int sum[1000005];
char s[1000005];
int dp[1000005][2];
int main()
{
	int t;
	cin >> t;
	while(t--){
		cin >> n >> k;  //scanf输入,下面输入字符串很难受
		cin >> s+1; 
		for(int i = 1; i <= n; ++i){
			sum[i]=sum[i-1]+(s[i]=='1');
		}
		int temp;
		for(int i = 1; i <= n; ++i){
			temp=max(0,i-k);//需要注意i-k 
			dp[i][0]=min(dp[i-1][0],dp[i-1][1])+(s[i]=='1');
			dp[i][1]=min(dp[temp][1]+sum[i-1]-sum[temp],sum[i-1])
			+(s[i]=='0');
		}
		cout << min(dp[n][0],dp[n][1]) << endl;
		for(int i = 0; i <= n; ++i){
			dp[i][0]=0,dp[i][1]=0,sum[i]=0;//别忘了初始化 
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章