#333. 【NOIP2017】宝藏

http://uoj.ac/problem/333

1、错误的$n^42^n$做法:

dp[s]表示当前的点集为s,然后从这些点中选一个做起点i,然后枚举边,然后更新dp[t|(1<<j)]。dis[s][i]表示点集为s的情况下的i号点的深度。详见代码。

为什么是错的,不满足当前最优一定是最后最优。比如下面的hack数据,正确答案应该是10420,即从4号点出发,长度为1的那条边不要。而在上面的dp中,点集为234的状态中只能从24和34转移而来,而这两个取最小值的时候,一定会算上1这条边,答案为12,而不是10这条边。导致下一步dp的时候,深度边长,导致更不优。

 #include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cmath>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<bitset>
using namespace std;
typedef long long LL; //char buf[100000], *p1 = buf, *p2 = buf;
//#define nc() p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++ inline int read() {
int x = , f = ; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch=='-') f = -;
for (; isdigit(ch); ch = getchar()) x = x * + ch - ''; return x * f;
} const int N = ;
const LL LLINF = 1e18;
const int INF = 1e9; LL dp[( << ) + ];
int mp[N][N], dis[( << ) + ][];
int n, m; LL solve(int x) {
memset(dis, , sizeof(dis));
int S = ( << n) - ; for (int s = ; s <= S; ++s) dp[s] = LLINF;
dis[ << x][x] = , dp[ << x] = ; for (int s = , t; s <= S; ++s) { // 点集
if (dp[s] == LLINF) continue;
cout << bitset<>(s) << "\n";
for (int i = ; i < n; ++i) { // 选一个点当起点
if (!((s >> i) & )) continue;
for (int j = ; j < n; ++j) { // 到达的下一个点
if (i == j || mp[i][j] == INF || ((s >> j) & )) continue;
t = s | ( << j);
cout << bitset<>(t) << "\n";
if (dp[t] > dp[s] + dis[s][i] * mp[i][j]) {
dp[t] = dp[s] + dis[s][i] * mp[i][j];
for (int k = ; k < n; ++k) dis[t][k] = dis[s][k];
dis[t][j] = dis[s][i] + ;
cout << dp[t] << "\n";
}
}
}
}
return dp[S];
} int main() {
// freopen("1.txt", "r", stdin);
// freopen("2.txt", "w", stdout);
n = read(), m = read(); for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j) mp[i][j] = INF;
for (int i = ; i <= m; ++i) {
int u = read() - , v = read() - , w = read();
mp[u][v] = min(mp[u][v], w), mp[v][u] = min(mp[v][u], w);
} LL ans = 1e18;
for (int i = ; i < n; ++i)
ans = min(ans, solve(i));
cout << ans; return ;
}
/* hack数据:
dp不满足,当前最优,不满足最后的答案最优 6 14
1 2 101
1 3 44
1 4 235
1 6 629
2 3 60
2 4 196
2 5 250
2 6 490
3 4 237
3 5 114
3 6 715
4 5 166
4 6 432
5 6 932 6 6
1 2 100
2 3 1
2 4 10
3 4 10
3 5 100
4 6 10000 */

2、那么解决上述dp中出现的dp,就需要按深度进行dp,每次枚举下一深度的所有点,子集dp。复杂度$n^33^n$

 #include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cmath>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<bitset>
using namespace std;
typedef long long LL; inline int read() {
int x = , f = ; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch=='-') f = -;
for (; isdigit(ch); ch = getchar()) x = x * + ch - ''; return x * f;
} const int N = ;
const LL LLINF = 1e18;
const int INF = 1e9; LL dp[( << ) + ][], tmp[( << ) + ], dis[N];
int mp[N][N];
int n, m; LL solve(int x) {
int S = ( << n) - ;
for (int s = ; s <= S; ++s)
for (int i = ; i <= n; ++i) dp[s][i] = LLINF;
dp[ << x][] = ; for (int s = ; s <= S; ++s) {
int r = ;
for (int i = ; i < n; ++i) dis[i] = LLINF;
for (int i = ; i < n; ++i) {
if ((s >> i) & )
for (int j = ; j < n; ++j)
if (!((s >> j) & ) && mp[i][j])
r |= ( << j), dis[j] = min(dis[j], (LL)mp[i][j]);
}
for (int t = r; t; t = (t - ) & r) {
tmp[t] = ;
for (int i = ; i < n; ++i)
if ((t >> i) & ) tmp[t] += dis[i];
}
for (int d = ; d <= n; ++d) {
if (dp[s][d] == LLINF) continue;
for (int t = r; t; t = (t - ) & r)
dp[s | t][d + ] = min(dp[s | t][d + ], dp[s][d] + tmp[t] * d);
}
}
LL ans = LLINF;
for (int i = ; i <= n; ++i) ans = min(ans, dp[S][i]);
return ans;
} int main() { n = read(), m = read(); for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j) mp[i][j] = INF;
for (int i = ; i <= m; ++i) {
int u = read() - , v = read() - , w = read();
mp[u][v] = min(mp[u][v], w), mp[v][u] = min(mp[v][u], w);
} LL ans = 1e18;
for (int i = ; i < n; ++i)
ans = min(ans, solve(i));
cout << ans; return ;
}

3、随机化算法

#333. 【NOIP2017】宝藏的更多相关文章

  1. 【比赛】NOIP2017 宝藏

    这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...

  2. [NOIP2017]宝藏 状压DP

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

  3. [NOIP2017]宝藏 子集DP

    题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...

  4. NOIP2017宝藏 [搜索/状压dp]

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

  5. NOIP2017 - 宝藏

    LibreOJ链接 Description 给出一个\(n(n\leq12)\)个点\(m(m\leq1000)\)条边的带权无向图,求该图的一棵生成树,使得其边权×该边距根的深度之和最小. Solu ...

  6. Luogu 3959 [NOIP2017] 宝藏

    NOIP2017最后一道题 挺难想的状压dp. 受到深度的条件限制,所以一般的状态设计带有后效性,这时候考虑把深度作为一维,这样子可以保证所有状态不重复计算一遍. 神仙预处理:先处理出一个点连到一个集 ...

  7. 洛谷P3959 [NOIP2017]宝藏

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

  8. NOIP2017 宝藏 题解报告【状压dp】

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

  9. 【洛谷P3959】[NOIP2017] 宝藏

    宝藏 题目链接 首先,打了一个prim,得了45分 #include<iostream> #include<cstring> #include<cstdio> #i ...

  10. [NOIP2017] 宝藏 【树形DP】【状压DP】

    题目分析: 这个做法不是最优的,想找最优解请关闭这篇博客. 首先容易想到用$f[i][S][j]$表示点$i$为根,考虑$S$这些点,$i$的深度为$j$情况的答案. 转移如下: $f[i][S][j ...

随机推荐

  1. BZOJ 1012 最大数maxnumber 线段树

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1012 题目大意: 见链接 思路: 直接用线段树模拟一下就可以了. #include&l ...

  2. 业务id转密文短链的一种实现思路

    业务场景: 买家通过电商app下单后,会受到一条短信,短信内容中包括改订单详情页面的h5地址连接,因为是出现在短信中,所以对连接有要求: 1.尽量短:2.安全性考虑,订单在数据库中对应的自增主键id不 ...

  3. 组合测试(Combinatorial Test)/配对测试 (pairwise)

    组合测试方法:配对测试实践 实施组合测试 常用的Pairwise工具集:http://www.pairwise.org/tools.asp 成对测试(Pairwise Testing)又称结对测试.两 ...

  4. JS获值

    var json = []; $('#hdtj table').each(function(index){ json.push({ 'con_main':$(this).find('input[nam ...

  5. 利用JDK自带工具keyTool生成安全证书

    前言:说一下最近做的工作,主要利用iText给网页中生成好的html报表转化为pdf格式的文件,并且在其中加入水印,数字签名等等,这部分主要介绍安全证书的目的就是为了做数字签名部分用的. 下面利用jd ...

  6. php多进程编程实现与优化

    PHP多进程API 创建子进程 @params void @returns int int pcntl_fork(void) 成功时,在父进程执行线程内返回产生的子进程PID,在子进程执行线程内返回0 ...

  7. Microsoft Visio / Project professional 2013 官方版本(下载)

    Microsoft Visio微软开发的一款软件, 它有助于 IT 和商务专业人员轻松地可视化.分析和交流复杂信息. 它能够将难以理解的复杂文本和表格转换为一目了然的 Visio 图表. 该软件通过创 ...

  8. SQL Server 数据收缩

    1. 数据库的相关属性 在MS中创建数据库时会为数据库分配初始的大小(如下图:数据库和日志两个文件),随着数据库的使用文件会逐渐增大.数据库文件大小的增加有两种方式: 自动增长:在自动增长中可以设置每 ...

  9. iOS开发UI篇 -- UISearchBar 属性、方法详解及应用(自定义搜索框样式)

    很多APP都会涉及到搜索框,苹果也为我们提供了默认的搜索框UISearchBar.但实际项目中我们通常需要更改系统默认搜索框的样式.为了实现这一目标,我们需要先搞懂 UISearchBar 的属性及方 ...

  10. No active profile set, falling back to default profiles: default

    No active profile set, falling back to default profiles: default 这个错误是由于idea没有设置默认启动环境,设置即可