Bribing FIPA

给出多棵有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 <iostream>
#include <cstdio>
#include <sstream>
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<<b<<' '<<c<<' '<<d;
return 0;
}
  • .clear()

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

#include <iostream>
#include <cstdio>
#include <sstream>
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 <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <sstream>
#define il inline
#define ri register
#define lsytql true
#define intmax 0x7fffffff
using 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<string,int>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]<ans)ans=dp[0][i];
printf("%d\n",ans);
}
return 0;
}
il int min(int a,int b){
return a<b?a:b;
}
void dfs(int x){
check[x]|=true,dp[x][0]=0;
for(int i(head[x]);i;i=ar[i].next)
if(!check[ar[i].to]){
dfs(ar[i].to),st[x]+=st[ar[i].to];
for(int j(n),k;j>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;
}

Bribing FIPA的更多相关文章

  1. POJ 3345 Bribing FIPA 树形DP

    题目链接: POJ 3345 Bribing FIPA 题意: 一个国家要参加一个国际组织,  需要n个国家投票,  n个国家中有控制和被控制的关系, 形成了一颗树. 比如: 国家C被国家B控制, 国 ...

  2. poj3345 Bribing FIPA【树形DP】【背包】

    Bribing FIPA Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5910   Accepted: 1850 Desc ...

  3. HDU 2415 Bribing FIPA

    Bribing FIPA Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original I ...

  4. POJ3345 Bribing FIPA

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5021   Accepted: 1574 Description There ...

  5. poj 3345 Bribing FIPA (树形背包dp | 输入坑)

    题目链接:  poj-3345  hdu-2415 题意 有n个国家,你要获取m个国家的支持,获取第i个国家的支持就要给cost[i]的价钱    其中有一些国家是老大和小弟的关系,也就是说,如果你获 ...

  6. POJ3345 Bribing FIPA 【背包类树形dp】

    题目链接 POJ 题解 背包树形dp板题 就是读入有点无聊,浪费了很多青春 #include<iostream> #include<cstdio> #include<cm ...

  7. POJ3345 Bribing FIPA(树形DP)

    题意:有n个国家,贿赂它们都需要一定的代价,一个国家被贿赂了从属这个国家的国家也相当于被贿赂了,问贿赂至少k个国家的最少代价. 这些国家的从属关系形成一个森林,加个超级根连接,就是一棵树了,考虑用DP ...

  8. [POJ 3345] Bribing FIPA

    [题目链接] http://poj.org/problem?id=3345 [算法] 树形背包 [代码] #include <algorithm> #include <bitset& ...

  9. 别人整理的DP大全(转)

    动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...

随机推荐

  1. WPF 从服务器下载文件

    1.先获取服务器下载地址,给出要下载到的目标地址 public void DownloadFileFromServer() { string serverFilePath = "http:/ ...

  2. Codeforces 1150D DP

    题意:给你一个长度为n的字符串,有q次询问,每次询问会给字符串x的末尾添加一个字符y,或者删除字符串x末尾的字符,询问过后,要判断长度为n的字符串中是否有3个不重合的子序列,是这3个字符串. 思路:设 ...

  3. Eclipse中发布Maven管理的Web项目时找不到类的问题根源和解决办法(转)

    转自:http://blog.csdn.net/lvguanming/article/details/37812579?locationNum=12 写在前面的话 现在是越来越太原讨厌Eclipse这 ...

  4. push declined due to email privacy restrictions

    使用git push到Github网站的时候提示: push declined due to email privacy restrictions 原因 在Github设置里有一个隐私选项 Block ...

  5. Windows cmd 打开面板

    { 打开控制面板的命令是:“control”  打开控制面板  命令: rundll32.exe shell32.dll,Control_RunDLL  结果: 显示控制面板窗口.  例子:  Cal ...

  6. 线性dp——1197D

    一开始没有什么头绪,后来注意到m<=10,考虑是否可以用dp[i][j]表示第i位,前面跟了j个数的最大值 那么第i+1个数,直接和第i个数的[0,m]的m+1种状态去转移即可,如果是由0或m状 ...

  7. 暴力——cf557c

    //枚举高度[1,100000],>l的全部割掉,<l的砍掉最小的 #include<bits/stdc++.h> using namespace std; #define N ...

  8. Ubuntu 14.04/16.04/18.04安装最新版Eigen3.3.5

    https://blog.csdn.net/xiangxianghehe/article/details/81236299 sudo cp -r /usr/local/include/eigen3 / ...

  9. The method setPositiveButton(int, DialogInterface.OnClickListener) in the type AlertDialog.Builder i

    参考资料: http://blog.csdn.net/competerh_programing/article/details/7377950 在创建Dialog的时候,出现: The method ...

  10. Code::Blocks

    Code::Blocks 是一个开放源码的全功能的跨平台C/C++集成开发环境. Code::Blocks是开放源码软件.Code::Blocks由纯粹的C++语言开发完成,它使用了著名的图形界面库w ...