博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
保安站岗
阅读量:4332 次
发布时间:2019-06-06

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

一道比较典型的树形\(DP\)吧。

  • 思路:
    \(f[i][0/1][0/1]\)表示第\(i\)个点有没有安排保安(第二维),能不能被观察到(第三维),其实开两维就可以。
    对于一个点\(u\),枚举它所有的儿子\(v\)注意是求和)。
    \(f[u][1][1]\)对儿子的所有情况(三种\(f[v][0][0]\,,[1][1]\,,[0][1]\))取\(min\)
    \(f[u][0][0]\)\(f[v][0][1]\,,[1][1]\)两种情况取\(min\)
    \(f[u][0][1]\)稍微复杂一点,于是对\(f[v][0][1]\,,[1][1]\)两种情况取\(min\),但是有可能所有的儿子都取的是\(f[v][0][1]\),这样就不合法了,必须至少有一个儿子取到\(f[v][1][1]\),才满足\(u\)点布设保安,但是被观察到(到目前为止)。所以枚举每个儿子的时候,记录一个\(f[v][1][1]-f[v][1][0]\)的最小值\(minn\),再设一个标记,如果有一个儿子取到了\(f[v][1][1]\),标记一下。如果到最后一直没有标记过,那么\(f[u][0][1]\)还得加上\(minn\)。意思是将一个儿子标记上,那么要减掉之前加上去的\(f[v][0][1]\),再加上\(f[v][1][1]\),选这样新产生贡献的最小\(v\)

最后取\(f[1][0][1]\)\(f[1][1][1]\)中较小的一个就行。

一直卡在90分上过不了的原因:

enter image description here

enter image description here

认真看题!!!

竟然还有90分,出题人真良心。

#include
#include
#include
#include
using namespace std;int n,f[1505][2][2],ans;// 2-> 0 1 表示i能不能被覆盖 int head[1505],tot,w[1505];struct edge{ int node,next;}e[3005];void add(int x,int y){ e[++tot].node=y; e[tot].next =head[x]; head[x]=tot;}void dfs(int u,int fa){ f[u][1][1]=w[u]; bool flag=0; int minn=0x7ffffff; for(int i=head[u];i;i=e[i].next) { int v=e[i].node; if(v==fa) continue; dfs(v,u); /* f[u][0][0]=min(f[u][0][0],f[v][0][1]); f[u][0][1]=min(f[u][0][1],f[v][1][1]); f[u][1][1]=min(f[u][1][1],min(f[v][0][0],min(f[v][0][1],f[v][1][1]))+w[u]); minn=min(minn,f[v][1][1]);(水平倒退www)*/ f[u][0][0]+=min(f[v][0][1],f[v][1][1]); minn=min(minn,f[v][1][1]-f[v][0][1]); if(f[v][1][1]>f[v][0][1]) f[u][0][1]+=f[v][0][1]; else f[u][0][1]+=f[v][1][1],flag=1; f[u][1][1]+=min(f[v][1][1],min(f[v][0][1],f[v][0][0])); } /* f[u][0][1]=min(f[u][0][1],minn); if(!flag) f[u][0][0]=0,f[u][1][1]=w[u]; */ //只要儿子中有一个安排了保安,u就会被覆盖到 //如果儿子中都没有安排保安,那么就选一个替换 if(!flag) f[u][0][1]+=minn; }int main(){// memset(f,0x7f,sizeof(f)); scanf("%d",&n); int x,y,k; for(int i=1;i<=n;++i) { scanf("%d",&x); scanf("%d%d",&w[x],&k); for(int j=1;j<=k;++j) { scanf("%d",&y); add(x,y); add(y,x); } } dfs(1,0); ans=min(f[1][1][1],f[1][0][1]); printf("%d\n",ans); return 0;}

转载于:https://www.cnblogs.com/karryW/p/11477850.html

你可能感兴趣的文章
小D课堂 - 新版本微服务springcloud+Docker教程_5-03 feign结合hystrix断路器开发实战上...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-01 微服务网关介绍和使用场景
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-05熔断降级服务异常报警通知
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-03 高级篇幅之zuul常用问题分析
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_5-08 断路器监控仪表参数
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_6-02 springcloud网关组件zuul
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-1.快速搭建SpringBoot项目,采用Eclipse...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-4.在线教育后台数据库设计...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-3.热部署在Eclipse和IDE里面的使用...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_1-3.在线教育站点需求分析和架构设计...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-4.后端项目分层分包及资源文件处理...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-2.快速搭建SpringBoot项目,采用IDEA...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-5.PageHelper分页插件使用
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-6.微信扫码登录回调本地域名映射工具Ngrock...
查看>>
小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-8.用户模块开发之保存微信用户信息...
查看>>
代码片段收集
查看>>
vue-cli3创建项目时报错
查看>>
输入1-53周,输出1-53周的开始时间和结束时间
查看>>
实验二
查看>>
shell——按指定列排序
查看>>