【atcoedr习题】

目录

D - Gomamayo Sequence

E - Minimize Sum of Distances


D - Gomamayo Sequence

题意是一个01字符串,把它变成只有一组相邻的0或相邻的1,改变每个字符都有一个代价

f1[i][0]表示从左到右把字符串变成01交错且第i个是0的最小代价
f2[i][0]表示从右到左把字符串变成01交错且第i个是0的最小代价 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
char s[N];
ll f1[N][2],f2[N][2];
int c[N];
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>s[i];
	for(int i=1;i<=n;i++)cin>>c[i];
	for(int i=1;i<=n;i++){
		for(int j=0;j<2;j++){
			f1[i][j]=f1[i-1][j^1]+(s[i]==j+'0')*c[i];
		}
	}
	for(int i=n;i>=1;i--){
		for(int j=0;j<2;j++){
			f2[i][j]=f2[i+1][j^1]+(s[i]==j+'0')*c[i];
		}
	}
	ll ans=1e17;
	for(int i=2;i<=n;i++){
		ans=min(ans,f1[i-1][0]+f2[i][0]);
		ans=min(ans,f1[i-1][1]+f2[i][1]);
	}
	cout<<ans<<'\n';
}

        

         

E - Minimize Sum of Distances

就是换根dp 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long N=1e5+10,inf=1e18;
int n,c[N];
ll f[N],sum[N],res,ans;
vector<int>g[N];
//void dfs1(int u,int fa,int d){
//	sum[u]=c[u];
//	res+=1ll*d*c[u];
//	for(auto v:g[u]){
//		if(v==fa)continue;
//		dfs1(v,u,d+1);
//		sum[u]+=sum[v];
//	}
//}
//void dfs2(int u,int fa){
//	ans=min(ans,res);
//	for(auto v:g[u]){
//		if(v==fa)continue;
//		res-=sum[v];
//		res+=sum[1]-sum[v];
//		dfs2(v,u);
//		res+=sum[v];
//		res-=sum[1]-sum[v];
//	}
//}
void dfs1(int u,int fa,int d){
	sum[u]=c[u];
	f[1]+=1ll*d*c[u];
	for(auto v:g[u]){
		if(v==fa)continue;
		dfs1(v,u,d+1);
		sum[u]+=sum[v];
	}
}
void dfs2(int u,int fa){
	for(auto v:g[u]){
		if(v==fa)continue;
		f[v]=f[u]-2*sum[v]+sum[1];
		dfs2(v,u);
	}
}
int main(){
	cin>>n;
	ans=inf;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	for(int i=1;i<=n;i++)cin>>c[i];
	dfs1(1,0,0);
	dfs2(1,0);
//	cout<<ans<<'\n';
	for(int i=1;i<=n;i++){
	if(f[i]<ans)ans=f[i];
	}cout<<ans;
}

        

        

思路:

 一道非常典型的反悔贪心,反悔贪心就是我们需要建立一个贪心堆,先按照正常的思路(局部最优)进行贪心,如果当前取出的不是最优解,那就范湖

#include <bits/stdc++.h>
using namespace std;
const int N=4e+5;
bool mark[N];
int n,m,l[N],r[N],ans,a[N],tot;
struct node{
	int id,v;
};
priority_queue<node>q;
bool operator<(const node &x,const node &y){
	return x.v<y.v;
}
int main(){
	cin>>n>>m;
	if(m>n/2){
		cout<<"Error!";return 0;
	}
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=2;i<n;i++){
		l[i]=i-1,r[i]=i+1; //创建环形链表
		q.push({i,a[i]});//加入大根堆
	}
	l[1]=n;r[1]=2;l[n]=n-1;r[n]=1;//起点和尾点
	q.push({1,a[1]});q.push({n,a[n]});
	tot=n;
	for(int i=1;i<=m;i++){
		node cur;cur=q.top();q.pop();
		if(mark[cur.id]){i--;continue;}//已经被删掉的点就跳过,注意i--,别又浪费了一袋
		ans+=cur.v;//更新答案
		a[++tot]=a[l[cur.id]]+a[r[cur.id]]-a[cur.id];//创建反悔点
		q.push({tot,a[tot]});//反悔点入堆
		l[tot]=l[l[cur.id]];r[tot]=r[r[cur.id]];//更新新节点的左右关系
		r[l[l[cur.id]]]=tot;l[r[r[cur.id]]]=tot;//新节点的左右节点的指向新节点
		mark[cur.id]=mark[l[cur.id]]=mark[r[cur.id]]=1;//删掉3个点
	}
	cout<<ans;
	return 0;
}

相关推荐

  1. 数据库——习题

    2024-06-09 23:08:05       49 阅读
  2. springboot习题

    2024-06-09 23:08:05       25 阅读
  3. 计算机网络——习题

    2024-06-09 23:08:05       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-09 23:08:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-09 23:08:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-09 23:08:05       82 阅读
  4. Python语言-面向对象

    2024-06-09 23:08:05       91 阅读

热门阅读

  1. Nginx 的 stream 模块,配置转发redis和mysql

    2024-06-09 23:08:05       30 阅读
  2. SpringBoot解决跨域的三种解决方案

    2024-06-09 23:08:05       30 阅读
  3. 自然资源-不动产登记资料查询暂行办法

    2024-06-09 23:08:05       33 阅读
  4. MySQL-备份恢复(四)

    2024-06-09 23:08:05       31 阅读
  5. qt 画图 持续更新

    2024-06-09 23:08:05       30 阅读
  6. 使用redis构建简单的社交网站

    2024-06-09 23:08:05       30 阅读
  7. 算法训练营第四十九天 | LeetCode 139单词拆分

    2024-06-09 23:08:05       26 阅读
  8. 《Linux内核精通》笔记参考目录

    2024-06-09 23:08:05       19 阅读
  9. tengine+lua的镜像制作

    2024-06-09 23:08:05       29 阅读