题意:

思路:n<=12,考虑状压DP

生成树中深度相同的点可以一次性转移完毕

设dp[sta,i]为已转移完sta状态的点,当前深度为i的最小花费

dp[sta or v,i+1]=min(dp[sta,i]+f[sta,v]*(i+1)),其中v是sta关于全集(1<<n)-1的补集v1的一个子集,这一步需要枚举子集

考场上写的O(3^n*n^2),没有预处理f[sta,v]而是每次都算了一遍,有进一步优化的空间

 const max=;
var dp,dis:array[..,..]of int64;
f:array[..,..]of int64;
n,m,i,j,x,y,z,k,maxs,v,v1:longint;
s,ans:int64; function min(x,y:int64):int64;
begin
if x<y then exit(x);
exit(y);
end; begin
assign(input,'treasure.in'); reset(input);
assign(output,'treasure.out'); rewrite(output);
readln(n,m);
for i:= to n do
for j:= to n do f[i,j]:=<<;
for i:= to n do f[i,i]:=;
for i:= to m do
begin
readln(x,y,z);
f[x,y]:=min(f[x,y],z);
f[y,x]:=min(f[y,x],z);
end;
maxs:=(<<n)-;
for i:= to maxs do
for j:= to n do
if i and (<<(j-))= then
begin
dis[i,j]:=<<;
for k:= to n do
if (j<>k)and(i and (<<(k-))>) then dis[i,j]:=min(dis[i,j],f[j,k]);
end; m:=maxs;
for i:= to maxs do
for j:= to n+ do dp[i,j]:=<<;
for i:= to n do dp[<<(i-),]:=;
for i:= to n do
for j:= to maxs do
begin
v:=j xor m; v1:=v;
while v> do
begin
s:=;
for k:= to n do
if v and (<<(k-))> then
begin
s:=s+dis[j,k];
if s>=(<<) then break;
end;
if s<(<<) then
dp[j or v,i+]:=min(dp[j or v,i+],dp[j,i]+s*(i+));
v:=v1 and (v-);
end;
end;
ans:=<<;
for i:= to n+ do ans:=min(ans,dp[maxs,i]);
if n= then ans:=;
writeln(ans); close(input);
close(output);
end.

O(3^n*n),预处理两个值

d[sta,i]      已取sta状态中的点到i点的最小值 预处理O(2^n*n^2)

f[x,y]      x状态中的点和y状态中的所有点连接最小长度之和=f[x,y-lowbit(y)]+d[x,z],z表示y中最后一个1的位置 预处理O(4^n) 需要保证x与y没有交集

 const max=;
var dp,d:array[..,..]of int64;
dis:array[..,..]of int64;
f:array[..,..]of int64;
num:array[..]of longint;
n,m,i,j,x,y,z,k,maxs,v,v1:longint;
s,ans:int64; function min(x,y:int64):int64;
begin
if x<y then exit(x);
exit(y);
end; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; begin
assign(input,'treasure.in'); reset(input);
assign(output,'treasure.out'); rewrite(output);
readln(n,m);
for i:= to n do
for j:= to n do f[i,j]:=<<;
for i:= to n do f[i,i]:=;
for i:= to m do
begin
readln(x,y,z);
f[x,y]:=min(f[x,y],z);
f[y,x]:=min(f[y,x],z);
end; maxs:=(<<n)-;
for i:= to maxs do
for j:= to n do
if i and (<<(j-))= then
begin
d[i,j]:=<<;
for k:= to n do
if (j<>k)and(i and (<<(k-))>) then d[i,j]:=min(d[i,j],f[j,k]);
end; m:=maxs;
for i:= to do num[<<(i-)]:=i;
for i:= to maxs do
for j:= to maxs do dis[i,j]:=<<;
for i:= to maxs do dis[,i]:=;
for i:= to maxs do dis[i,]:=; for i:= to maxs do
for j:= to maxs do
if i and j= then
begin
x:=num[lowbit(j)];
dis[i,j]:=dis[i,j-lowbit(j)]+d[i,x];
if dis[i,j]>(<<) then dis[i,j]:=<<;
end; for i:= to maxs do
for j:= to n+ do dp[i,j]:=<<;
for i:= to n do dp[<<(i-),]:=;
for i:= to n do
for j:= to maxs do
begin
v:=j xor m; v1:=v;
while v> do
begin
if dis[j,v]<<< then
dp[j or v,i+]:=min(dp[j or v,i+],dp[j,i]+dis[j,v]*(i+));
v:=v1 and (v-);
end;
end; ans:=<<;
for i:= to n+ do ans:=min(ans,dp[maxs,i]);
if n= then ans:=;
writeln(ans); close(input);
close(output);
end.

【NOIP2017】宝藏(状压DP)的更多相关文章

  1. [NOIP2017]宝藏 状压DP

    [NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...

  2. 洛谷$P3959\ [NOIp2017]$ 宝藏 状压$dp$

    正解:状压$dp$ 解题报告: 传送门$QwQ$ $8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$ 发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j} ...

  3. Luogu 3959 [NOIP2017] 宝藏- 状压dp

    题解 真的想不到这题状压的做法...听说还有跑的飞快的模拟退火,要是现场做绝对滚粗QAQ. 不考虑深度,先预处理出 $pt_{i, S}$ 表示让一个不属于 集合 $S$ 的 点$i$ 与点集 $S$ ...

  4. $[NOIp2017]$ 宝藏 状压$dp$

    \(Sol\) 觉得这里是个很巧妙的地方吖,就是记下当前扩展点集的最大深度,然后强制下一步扩展的点集都是最大深度+1.这样做在当前看可能会导致误算答案导致答案偏大,但是整个\(dp\)完成后一定可以得 ...

  5. Luogu3959 NOIP2017 宝藏 状压DP

    题目传送门:https://www.luogu.org/problemnew/show/P3959 题意:给出一个有$N$个点的图,求其中的一个生成树(指定一个点为根),使得$\sum\limits_ ...

  6. P3959 宝藏 状压dp

    之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正 ...

  7. [Luogu P3959] 宝藏 (状压DP+枚举子集)

    题面 传送门:https://www.luogu.org/problemnew/show/P3959 Solution 这道题的是一道很巧妙的状压DP题. 首先,看到数据范围,应该状压DP没错了. 根 ...

  8. NOIp2017D2T2(luogu3959) 宝藏 (状压dp)

    时隔多年终于把这道题锅过了 数据范围显然用搜索剪枝状压dp. 可以记还有哪些点没到(或者已到了哪些点).我们最深已到的是哪些点.这些点的深度是多少,然后一层一层地往下推. 但其实是没必要记最深的那一层 ...

  9. 计蒜客 宝藏 (状压DP)

    链接 : Here! 思路 : 状压DP. 开始想直接爆搜, T掉了, 然后就采用了状压DP的方法来做. 定义$f[S]$为集合$S$的最小代价, $dis[i]$则记录第$i$个点的"深度 ...

  10. loj2318 「NOIP2017」宝藏[状压DP]

    附带其他做法参考:随机化(模拟退火.爬山等等等)配合搜索剪枝食用. 首先题意相当于在图上找一颗生成树并确定根,使得每个点与父亲的连边的权乘以各自深度的总和最小.即$\sum\limits_{i}dep ...

随机推荐

  1. .net 字符串和JSON格式的互换

    近期又做了个问卷调查,问卷调查一次性要保存一二十个题目和答案!所以嘞,博主为了偷懒,就直接把答卷内容保存成了Json格式! 好处当然是很多啦! 只需一个字段就能保存整个答卷的内容! 想想都刺激!哈哈~ ...

  2. java之java.lang.UnsupportedClassVersionError:com/mysql/jdbc/Driver : Unsupported major.minor version 52.0

    问题解释:jdk版本和mysql驱动版本不兼容,比如:jdk1.7与mysql-connector-java-5.xxx兼容,但与mysql-connector-java-6.xxx及以上不兼容

  3. SQL常用自定义函数

    1.字符串转Table(Func_SplitToTable) CREATE FUNCTION [dbo].[Func_SplitToTable]      (        @SplitString ...

  4. hihocoder1705 座位问题

    思路: 使用堆模拟.复习了priority_queue自定义结构体比较函数的用法. 实现: #include <bits/stdc++.h> using namespace std; ty ...

  5. CF932C Permutation Cycle

    思路: 构造. 实现: #include <bits/stdc++.h> using namespace std; ]; int main() { int n, a, b; while ( ...

  6. 在阿里云上搭建nginx + ThinkPHP 的实践

    作为一个程序猿,理应用linux系统来作为平时的工作机环境,哎,之前倒是用过一段时间的linux,可惜后来换了本本,后来竟然没有保持,嗷嗷后悔中... 废话不多说,大家用windows的理由都一样,但 ...

  7. Windows 下 IIS与Apache 共存

    在Windows服务器下, 安装了IIS以及Apache服务器, 如何使他们一起工作. 目前我面对的问题是, 只有一个IP地址,要通过不同的端口来访问不同的程序. 解决方案如下: 1.找到 Apach ...

  8. IntelliJ IDEA安装与破解

    1.软件下载 文中使用到的安装包下载 2.部署 安装一路下一步即可. 把下载的JetbrainsCrack-3.1-release-enc.jar放在安装目录的bin目录下 3.修改配置文件 在安装的 ...

  9. Asp.Net 设计模式 之 “工厂方法”即利用 接口 实现的抽象工厂

    主要改动部分: /// <summary>    /// 6.创建工厂方法模式(抽象工厂:接口)    /// </summary>    interface IFactory ...

  10. pthread Win32多线程编程的一些知识和感想

    研究遗传算法的一大诟病就是每次运行程序的结果并不是完全一样的,有时候能找到最优解有时候找不到最优解,这就是遗传算法的概率性导致的.那么怎么评价你的方法的好坏呐,这时候就要多次独立运行程序最后取结果的平 ...