博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bribing FIPA
阅读量:6153 次
发布时间:2019-06-21

本文共 2600 字,大约阅读时间需要 8 分钟。

给出多棵有n个节点的有根树,第i个节点有一个权值\(a_i\),定义一个点能控制的点为其所有的子节点和它自己,询问选出若干个点的最少的权值之和,并且能够控制大于等于m个点,\(1 ≤ n ≤ 200\)

此题卡输入,插点题外话


c++语法讲解:

  1. c++11将gets()函数弃用了,而代以更加安全的fgets(),原因为gets的读入为一定要读完一行,而实际上可以读的数据是无限的,而电脑的内存空间是有限的,用无限的数据去填满有限的内存,那是自然会死机的,于是fgets加了一个限制,一定要按你给的字符数组大小读入,自然不支持string。

  2. fgets(char数组名,sizeof(char数组名),stdin)

  3. streamstring是为了方便读入而引入的,比较老的c++版本是不会支持的,但放心的是oi肯定支持(类似一个类型)

  4. 用法(建议运行试一试)

参考代码

#include 
#include
#include
using namespace std;int main(){ char s[1000]; stringstream a;//a为变量名//读入7 afsfs 0.125 fgets(s,sizeof(s),stdin); a.clear(),a.str(s);//清空a,用s来填充a int b;string c;double d; a>>b,a>>c,a>>d; cout<
<<' '<
<<' '<
  • .clear()

清空状态标志,每次用完stringstream一定要清空,但未释放内存,可以做个小测试,打开内存显示,运行一下下面的程序,等待5s

#include 
#include
#include
using namespace std;int main(){ register stringstream io; while(true)io<<"lsy akioi",io.clear(); return 0;}
  • .str()

用字符串s来重置stringstream,释放了内存

  • \(>>,<<\)分别表示输入到和输出到

废话完结


回到题目,显然是树形递推,因为是森林,故用一个超级根0连上所有树根,变为一棵树,肯定设两维\(f[i][j]\)表示以i为节点的子树中,控制了j个点的选择权值之和的最小值,显然有

\[f[i][j]=f[i][j-k]+f[l][k]\]

其中l为i的一个子节点,k为其控制的点,也可以用分组背包来理解,i只不过代替不同的背包,j是容量,而子树就是每一组物品,k就是物品,只是压了子树这一维状态,设\(s[x]\)为x的子树中节点个数。

边界:\(f[x][0]=0,f[x][s[x]]=a_x,x=0,1,2,3,...,n\)特别地\(a_0=INT\_MAX\)

参考代码:

#include 
#include
#include
#include
#include
#define il inline#define ri register#define lsytql true#define intmax 0x7fffffffusing namespace std;struct point{ int next,to;}ar[401];bool check[201];int c[201],at,head[201], in[201],dp[201][201], st[201],mt,n,m;char s[30000];stringstream oi;map
M;void dfs(int);il int min(int,int);il void link(int,int);int main(){ while(true){ mt&=0,M.clear(),memset(head,0,sizeof(head)),at&=0; memset(in,0,sizeof(in)),memset(check,0,sizeof(check)); memset(dp,2,sizeof(dp)),memset(st,0,sizeof(st)); fgets(s,sizeof(s),stdin),oi.clear(),oi.str(s),oi>>n>>m; if(s[0]=='#')break;for(int i(1),j;i<=n;++i){ fgets(s,sizeof(s),stdin); oi.clear(),oi.str(s),oi>>s; if(M.find(s)==M.end())M[s]=++mt; j=M[s],oi>>c[j]; while(oi>>s){ if(M.find(s)==M.end())M[s]=++mt; link(j,M[s]),++in[M[s]]; } }int ans(intmax); for(int i(1);i<=n;++i)if(!in[i])link(0,i);dfs(0); for(int i(m);i<=n;++i)if(dp[0][i]
0;--j) for(k=1;k<=j;++k) dp[x][j]=min(dp[x][j],dp[x][j-k]+dp[ar[i].to][k]); }++st[x],dp[x][st[x]]=min(dp[x][st[x]],c[x]);}il void link(int u,int v){ ar[++at].to=v; ar[at].next=head[u],head[u]=at;}

转载于:https://www.cnblogs.com/a1b3c7d9/p/11007531.html

你可能感兴趣的文章
好记性不如烂笔杆-android学习笔记<十六> switcher和gallery
查看>>
JAVA GC
查看>>
3springboot:springboot配置文件(外部配置加载顺序、自动配置原理,@Conditional)
查看>>
前端第七天
查看>>
图解SSH原理及两种登录方法
查看>>
【总结整理】JQuery基础学习---样式篇
查看>>
查询个人站点的文章、分类和标签查询
查看>>
基础知识:数字、字符串、列表 的类型及内置方法
查看>>
JSP的隐式对象
查看>>
JS图片跟着鼠标跑效果
查看>>
[SCOI2005][BZOJ 1084]最大子矩阵
查看>>
学习笔记之Data Visualization
查看>>
Leetcode 3. Longest Substring Without Repeating Characters
查看>>
416. Partition Equal Subset Sum
查看>>
app内部H5测试点总结
查看>>
[TC13761]Mutalisk
查看>>
while()
查看>>
常用限制input的方法
查看>>
IIS7下使用urlrewriter.dll配置
查看>>
并行程序设计学习心得1——并行计算机存储
查看>>