2025/2/10课堂记录

news/2025/2/10 22:49:37/文章来源:https://www.cnblogs.com/yongshao/p/18708927

目录

  1. 选课
  2. 叶子的染色
  3. 数字转换

  • 选课

分组背包题

这次是自己写的代码了,也就瞟了标准答案几眼,真的就几眼

用的也是vector邻接表

#include<iostream>
#include<vector>
using namespace std;
vector <int>zi[110];//zi[i][j]:i的第j个孩子 (j动态大小 
int a[110],m,n,f[110][110];//f[i][j]:以i为根最多选j和节点,最大值 
void maketree(int root)
{for(int i=0;i<zi[root].size();i++){maketree(zi[root][i]);for(int j=m;j>=1;j--)for(int k=j;k>=1;k--)f[root][j]=max(f[root][j],f[root][j-k]+f[zi[root][i]][k]);}if(root!=0)for(int i=m;i>=1;i--)f[root][i]=f[root][i-1]+a[root];
}
int main()
{cin>>m>>n;//m:待选,n:可选 for(int i=1;i<=m;i++){int x,y;cin>>x>>y;zi[x].push_back(i);//表示x的孩子再多一个i a[i]=y;}maketree(0);cout<<f[0][n]; return 0;
}

话说vector真的比链式前向星好用唉


  • 叶子的染色

这是一道树形dp题

然后代码简单题难懂,主要解释一下题是啥意思

首先有一颗树,总共有m个节点,n个叶子结点

这n个叶子结点的编号是1-n

这棵树的根就是在n+1 - m这个区间随便选一个,代码上选的是n+1这个节点

其实题目里面告诉了是无根树,那么随便选哪一个非叶子节点当根结果都是一样的

至于样例,那么以n+1即节点4为树根进行演示

可以看到,只要将4染黑,2染白,就能达到1黑2白3黑的效果

因为4可以扩散到5、1,5可以再扩散到2、3,但2已经染过色了

代码用的链式前向星

剩下代码就很简单了,看看注释吧
 #include<iostream> 
using namespace std;
int c[10010],tot,f[100010][2],head[10010],m,n;
//f[i][0/1]:以i点作为子树树根,i点染成黑/白色时,整颗子树最小值 
struct EDGE
{int next,to;
}edge[100010];
void add(int from,int to)
{edge[++tot].to=to;edge[tot].next=head[from];head[from]=tot;
}
void dp(int root,int from)
{f[root][0]=1,f[root][1]=1;//染色就+1,后来会减掉 if(root<=n)//当前子树根节点为叶子结点if(c[root]==1)//白色 f[root][0]=0x3f3f3f3f;//肯定不可能是黑色 else//黑色 f[root][1]=0x3f3f3f3f;for(int i=head[root];i;i=edge[i].next)//遍历所有相连的点 if(edge[i].to!=from)//父亲除外,那就遍历所有孩子 {dp(edge[i].to,root);//每一个孩子节点作为子树树根,此节点作为父亲 f[root][0]+=min(f[edge[i].to][0]-1,f[edge[i].to][1]);
//如果root是黑色,他的孩子也是黑色的话,他孩子的那个染色就可以褪掉了,反之孩子还得染着色 f[root][1]+=min(f[edge[i].to][1]-1,f[edge[i].to][0]);	}
}
int main()
{cin>>m>>n;for(int i=1;i<=n;i++)cin>>c[i];for(int i=1;i<=m-1;i++){int x,y;cin>>x>>y;add(x,y);add(y,x);}dp(n+1,-1);//随便选一个不是叶子的节点都行,没有父亲为-1 cout<<min(f[n+1][1],f[n+1][0]);//贪心思想,根节点肯定要染色 
//	cout<<"\n";                                                       //test
//	for(int i=1;i<=m;i++)cout<<f[i][0]<<" "<<f[i][1]<<"\n";           //testreturn 0;
}

另外还有点贪心思想在里面,即根节点肯定要染色


  • 数字转换(作业)

这是一道树的直径题

树的直径,标准模板
 //  树的直径 dp实现; 
//  https://blog.csdn.net/qq_42211531/article/details/86579115
//  dp[u][0]: 结点u的最长儿子链
//  dp[u][1]: 结点u的次长儿子链 
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 100005;
int head[MAX], dp[MAX][2];
int n, s, cnt, ans;struct EDGE
{int v, w, next;
}e[MAX];void Add(int u, int v, int w)
{e[++cnt].v = v;e[cnt].w = w;e[cnt].next = head[u];head[u] = cnt;
}//   利用孩子的最长链去更新父亲的最长链和次长链 
void DFS(int u, int fa)
{//dp[u][0]:最长子链; dp[u][1]:次长子链 dp[u][0] = dp[u][1] = 0;for(int i = head[u]; i ; i = e[i].next){int v = e[i].v;int w = e[i].w;if(v != fa){DFS(v, u);if(dp[u][0] < dp[v][0] + w)   //    父亲u的最长 < 孩子v的最长 + (u,v)边长 {dp[u][1]= dp[u][0];dp[u][0] = dp[v][0] + w;}else if(dp[u][1] < dp[v][0] + w)dp[u][1] = dp[v][0] + w;}}//枚举经过每个节点的长链,是否最大? ans = max(ans, dp[u][1] + dp[u][0]);
}int main()
{memset(head, 0, sizeof(head));scanf("%d", &n);for(int i = 1; i <= n - 1; i++){int u, v, w;scanf("%d%d%d", &u, &v, &w);Add(u, v, w);Add(v, u, w);}DFS(1, -1);  //假设1作为无根树的树根; printf("%d\n",ans);
}
树的直径二次dp
 //https://blog.csdn.net/Rainfoo/article/details/105290837
//图论-树-最长链(树的直径) 
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
#define ll long long
const int maxn=2e5+5;
int d[maxn],head[maxn],f_num,ans,tot;
struct E{int to,next,w;
}edge[maxn];
void add(int u,int v,int z){edge[tot].to=v;edge[tot].w=z;edge[tot].next=head[u];head[u]=tot++;
}
void dfs(int x,int fa){if(ans<d[x]){ans=d[x];f_num=x;}for(int i=head[x];i!=-1;i=edge[i].next){int v=edge[i].to;if(v==fa) continue;d[v]=d[x]+edge[i].w;dfs(v,x);}
}
int main(){memset(head,-1,sizeof(head));int n,m;cin>>n>>m;for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v;//cin>>w;add(u,v,w);add(v,u,w);}dfs(1,0);ans=0;d[f_num]=0;dfs(f_num,0);cout<<ans<<endl;
}
这个是数字转换的答案
 #include<iostream>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int INF=0x3f3f3f;
const double eps=1e-5;
const int maxn=5e4+10;
/*题意:若是一个数x的所有约数(不包括他自己)之和sum比他自己小,
那么x可以转化成sum,sum也可以成 x。例如 4可以变为 3,1可以变为7
限制所有数字变换在不跨越 n的正整数范围内举行转化,求不停举行数字变换且无重复数字的最多变换步数*/
int sum[maxn];//预处理每个数的约数之和
int f1[maxn],f2[maxn];//f1:以i为根的树中,i到叶子节点的最长距离,f2 :....次长距离
//直径就是 max(f1[i]+f2[i])  就是树中所有的两点最短距离中的最大值
//
int n;
void getsum()//预处理每个数的约数之和
{for(int i=1;i<=n;i++){for(int j=2;j<=n/i;j++){sum[i*j]+=i;  //i是i*j的约数 }}
}
int main()
{
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);scanf("%d",&n);getsum();for(int i=n;i>=1;i--){if(sum[i]>=i)  continue;//把sum[i]看成i的父亲,因为每个i的sum[i]都是唯一的 而能变成i的数不唯一if(f1[i]+1>f1[sum[i]]) {f2[sum[i]]=f1[sum[i]];f1[sum[i]]=f1[i]+1;}else if(f1[i]+1>f2[sum[i]]) f2[sum[i]]=f1[i]+1;}int ans=-1;for(int i=1;i<=n;i++) ans=max(ans,f1[i]+f2[i]);printf("%d\n",ans);return 0;
}

好不容易上了一节课,上着上着把烦恼忘了,这下好了,今晚又睡不着了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881894.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.4 什么是浮点数

很多编程语言中都提供了两种表示小数的数据类型,分别为双精度浮点数和单精度浮点数 双精度浮点数类型用64位、单精度浮点数类型用32位来表示全体小数。 在C语言中,双精度浮点数类型和单精度浮点数类型分别用double和float来表示 浮点数是指用符号、尾数、基数和指数这四部分来…

响应

ResponseBody注解 位置:controll类和方法 作用:将方法返回值直接相应,如果是实体对象和集合转成Json形式再相应、 统一响应格式 result里有静态方法

并行计算架构和编程 | 目录

from pixiv JW资源汇总 前言 开新坑了,尽量完成它吧. 此篇博客为目录章节,主要汇总学习过程中用到的资料,记录时间线。 SourceCS自学指南 CMU 15-418/Stanford CS149: Parallel Computing 了解此课程的主要起始地,下面的评论含有价值的信息 PKUFlyingPig/CS149-parallel-co…

使用Microsoft/Windows LAPS管理本地管理员密码

什么是LAPS Local Administrator Password Solution,简称LAPS,是微软提供的一种用于管理本地管理员密码的解决方案。用于在Active Directory(AD)环境中自动管理和轮换众多客户端Windows的本地管理员账户及密码。 在没有这个工具之前, 本地管理员密码管理会非常的复杂。比如…

Avalonia系列文章之布局简介

在UI设计中,页面布局非常重要,良好的布局不仅可以有效的利用空间,还能提升交互体验,以达到事半功倍的效果。所以对于Avalonia UI初学者来说,布局控件的了解与学习也非常的重要,今天以一些小例子,简述Avalonia UI框架中布局控件的使用,仅供学习分享使用,如有不足之处,…

ACM寒假集训第四期

ACM寒假集训第四期 有理数取余 思路 bx=a mod m x=((a mod m) * ( b^(-1) ) mod m)) mod m; 问题就转化为如何求解 b 的逆元 b x = 1 mod m ,b对m的逆元,当 gcd(b,m)=1 时才存在。存在 bx+my=1 通过辗转相除法可以得到b,m的最大公约数然后根据最后得到的一系列等式合并为 bx+m…

昆明理工大学2025年硕士研究生调剂汇总表(2月10日更新)

这是今年昆明理工大学调剂信息,目前只更新了部分学院的部分专业,后续会持续更新。 【腾讯文档】昆明理工大学2025年硕士研究生调剂汇总表 https://docs.qq.com/sheet/DZERIbnpPb3JjeHFO

推荐一款人人可用的开源 BI 工具,更符合国人使用习惯的数据可视化分析工具,数据大屏开发神器!

前言 今天大姚给大家推荐一款人人可用的开源、免费的 BI 工具,更符合国人使用习惯的数据可视化分析工具,数据大屏开发神器,Tableau、帆软的开源替代:DataEase。工具介绍 DataEase是一个开源的数据可视化分析工具,可以帮助用户快速分析数据并洞察业务趋势,从而实现业务的改…

清华大学推出的 DeepSeek 从入门到精通(104页)免费教程!

前言 最近 DeepSeek 的出现让 AI 在国内掀起了一股浪潮,各大媒体、平台都在讨论和推广 DeepSeek,帮助各行各样使用 AI 不再有困难。今天大姚给大家分享一个由清华大学推出的、免费的:DeepSeek从入门到精通实用教程,该教材有着足足的104页能够快速的帮助大家了解和使用DeepS…

卞俊良

卞俊良 你猜 你猜我猜不猜