#333. 【NOIP2017】宝藏
#333. 【NOIP2017】宝藏
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】宝藏的更多相关文章
- 【比赛】NOIP2017 宝藏
这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...
- [NOIP2017]宝藏 状压DP
[NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...
- [NOIP2017]宝藏 子集DP
题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...
- NOIP2017宝藏 [搜索/状压dp]
NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- NOIP2017 - 宝藏
LibreOJ链接 Description 给出一个\(n(n\leq12)\)个点\(m(m\leq1000)\)条边的带权无向图,求该图的一棵生成树,使得其边权×该边距根的深度之和最小. Solu ...
- Luogu 3959 [NOIP2017] 宝藏
NOIP2017最后一道题 挺难想的状压dp. 受到深度的条件限制,所以一般的状态设计带有后效性,这时候考虑把深度作为一维,这样子可以保证所有状态不重复计算一遍. 神仙预处理:先处理出一个点连到一个集 ...
- 洛谷P3959 [NOIP2017]宝藏
[题目描述] 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋,也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但 ...
- NOIP2017 宝藏 题解报告【状压dp】
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
- 【洛谷P3959】[NOIP2017] 宝藏
宝藏 题目链接 首先,打了一个prim,得了45分 #include<iostream> #include<cstring> #include<cstdio> #i ...
- [NOIP2017] 宝藏 【树形DP】【状压DP】
题目分析: 这个做法不是最优的,想找最优解请关闭这篇博客. 首先容易想到用$f[i][S][j]$表示点$i$为根,考虑$S$这些点,$i$的深度为$j$情况的答案. 转移如下: $f[i][S][j ...
随机推荐
- 异步模式:Callbacks, Promises & Async/Await
[译]异步JavaScript的演变史:从回调到Promises再到Async/Await https://www.i-programmer.info/programming/theory/8864- ...
- 【redis运维】redis自己主动安装脚本(仅仅安装redis)
Redis自己主动安装部署 本文总共分为4个部分: redis自己主动安装脚本文件夹结构说明: redis自己主动安装脚本内容: redis的操作系统服 ...
- C/C++ 格式化读取和读取一行
文件内容 23 21 4 1 1 0 114 1 1 1 8 112 5 0 0 0 114 1 0 0 0 115 52 4 1 0 1 134 4 0 1 12 131 4 1 1 0 133 5 ...
- 3、Spring Cloud - Eureka(高可用Eureka Server集群)
在实际的项目中,可能有几十个或者几百个的微服务实例,这时 Eureka Server 承担了非 常高的负载.由于 Eureka Server 在微服务架构中有着举足重轻的作用,所以需要对 Eureka ...
- Extjs自定义验证介绍
表单验证实例(空验证,密码确认验证,email验证) 我们可以用单独的js写表单验证,但是extjs已经为我们想到了(自己单独写反而不方便). 在验证之前,我不得不提两个小知识点: //大家在很多的e ...
- 安装IIS步骤图解
这几日好些网友来找iis安装包,但是因为新浪爱问的共享资料已关闭导致下载链接不可用,笔者在新浪微盘的备份资料只有5.1版,现共享链接如下: IIS5.1 for windows xp下载链接http: ...
- PAT——1034. 有理数四则运算
本题要求编写程序,计算2个有理数的和.差.积.商. 输入格式: 输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分 ...
- SDN测量论文粗读(二)9.21
Monocle: Dynamic,Fine-Grained Data Plane Monitoring 论文来源:CoNext 发表时间:2015 解决问题及所做贡献:Monocle:检测交换机中硬件 ...
- 苹果编程语言Swift简介
Swift是什么? Swift是苹果于WWDC 2014发布的编程语言,The Swift Programming Language的原话: Swift is a new programming la ...
- PyCharm 2018最新激活码通用
通用:Window.Mac.Ubantu都稳定有效,关键是这种激活方式不会产生其他影响 缺点:需要修改hosts文件 **1.修改hosts文件**将 0.0.0.0 account.jetbrain ...