洛谷 3959 宝藏——枚举+状压dp
题目:https://www.luogu.org/problemnew/show/P3959
原来写了个不枚举起点的状压dp。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=,M=(<<)+,INF=0x3f3f3f3f;
int n,m,lm,b[N][N],dis[M][N];
ll dp[M];
int main()
{
scanf("%d%d",&n,&m);lm=(<<n);
memset(b,0x3f,sizeof b);
int x,y,z;
while(m--)
{
scanf("%d%d%d",&x,&y,&z);
b[x][y]=min(b[x][y],z);b[y][x]=b[x][y];
}
memset(dp,0x3f,sizeof dp);dp[]=;
for(int i=;i<=n;i++)dp[<<(i-)]=,dis[<<(i-)][i]=;
for(int s=;s<lm;s++)
for(int i=;i<=n;i++) if((s&(<<(i-)))==)
{
int d=(s|(<<(i-)));
for(int j=;j<=n;j++) if(s&(<<(j-)))
if(dp[s]+(ll)b[i][j]*dis[s][j]<dp[d])//b可能是0x3f3f3f
{
dp[d]=dp[s]+(ll)b[i][j]*dis[s][j];
memcpy(dis[d],dis[s],sizeof dis[s]);
dis[d][i]=dis[s][j]+;
}
}
printf("%lld\n",dp[lm-]);
return ;
}
但其错误是不能改dis。没有最优子结构的性质。
然后看了题解,发现如果枚举起点,就行了。
其实和原来想的差不多,但原来的不同起点的dis最后会混到一起,进而少遍历一些状态。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=,M=(<<)+,INF=0x3f3f3f3f;
int n,m,lm,b[N][N],dis[N];
ll dp[M],ans=INF;
void dfs(int S)
{
for(int i=;i<=n;i++) if((S&(<<(i-)))==)
{
int D=(S|(<<(i-)));
for(int j=;j<=n;j++) if(S&(<<(j-))&&b[i][j]<INF)
if(dp[S]+b[i][j]*dis[j]<dp[D])
{
dp[D]=dp[S]+b[i][j]*dis[j];
dis[i]=dis[j]+;
dfs(D);
dis[i]=;
}
}
}
int main()
{
scanf("%d%d",&n,&m);lm=(<<n);
memset(b,0x3f,sizeof b);
int x,y,z;
while(m--)
{
scanf("%d%d%d",&x,&y,&z);
b[x][y]=min(b[x][y],z);b[y][x]=b[x][y];
}
for(int i=;i<=n;i++)
{
memset(dp,0x3f,sizeof dp);dp[<<(i-)]=;
memset(dis,0x3f,sizeof dis);dis[i]=;
dfs(<<(i-));
ans=min(ans,dp[lm-]);
}
printf("%lld\n",ans);
return ;
}
洛谷 3959 宝藏——枚举+状压dp的更多相关文章
- 洛谷P3959 宝藏(状压dp)
传送门 为什么感觉状压dp都好玄学……FlashHu大佬太强啦…… 设$f_{i,j}$表示当前选的点集为$i$,下一次要加入的点集为$j$时,新加入的点和原有的点之间的最小边权.具体的转移可以枚举$ ...
- 洛谷 P3959 宝藏【状压dp】
一开始状态设计错了-- 设f[i][s]为当前与根节点联通状况为s,最深深度为i 转移的话枚举当前没有和根联通的点集,预处理出把这些点加进联通块的代价(枚举s中的点和当前点的连边乘以i即可),然后用没 ...
- 【洛谷4941】War2 状压Dp
简单的状压DP,和NOIP2017 Day2 找宝藏 代码几乎一样.(比那个稍微简单一点) f[i][j] ,i代表点的状态,j是当前选择的点,枚举上一个选到的点k 然后从f[i-(1<< ...
- 洛谷 P1433 吃奶酪 状压DP
题目描述 分析 比较简单的状压DP 我们设\(f[i][j]\)为当前的状态为\(i\)且当前所在的位置为\(j\)时走过的最小距离 因为老鼠的坐标为\((0,0)\),所以我们要预处理出\(f[1& ...
- 洛谷 P3112 后卫马克 —— 状压DP
题目:https://www.luogu.org/problemnew/show/P3112 状压DP...转移不错. 代码如下: #include<iostream> #include& ...
- 2018.11.02 洛谷P2831 愤怒的小鸟(状压dp)
传送门 状压一眼题. 直接f[i]f[i]f[i]表示未选择状态为iii时的最小次数. 然后考虑现在怎么转移. 显然可以直接枚举消掉某一个点或者某两个点,复杂度O(n22n)O(n^22^n)O(n2 ...
- 洛谷P2473奖励关——状压DP
题目:https://www.luogu.org/problemnew/show/P2473 还是对DP套路不熟悉... 像这种前面影响后面,而后面不影响前面的问题就应该考虑倒序递推: 看n只有15那 ...
- 洛谷P4590 [TJOI2018]游园会(状压dp LCS)
题意 题目链接 Sol 这个题可能是TJOI2018唯一的非模板题了吧.. 考虑LCS的转移方程, \[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1] ...
- 洛谷 P1879 玉米田(状压DP入门题)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int M,N; int plant[maxn][maxn];/ ...
随机推荐
- JS数组 谁是团里成员(数组赋值)var myarray = new Array(66,80,90,77,59);//创建数组同时赋值
谁是团里成员(数组赋值) 数组创建好,接下来我们为数组赋值.我们把数组看似旅游团的大巴车,大巴车里有很多位置,每个位置都有一个号码,顾客要坐在哪个位置呢? 第一步:组个大巴车 第二步:按票对号入座 大 ...
- Entity Framework Code First 模式-建立多对多联系
Entity Framework 在建立多对多的联系时,会生成一个中间表,用来表示这个多对多的关系.这和数据库设计时从概念模型到逻辑模型转化时,多对多的关系不能和任何一端的实体合并,需要将关系也转化为 ...
- android 使用现成做get请求
//接受子线程发来的消息 Handler hanler = new Handler() { @Override public void handleMessage(Message msg) { // ...
- 廖雪峰Java12maven基础-2maven进阶-2模块管理
1. 把大项目拆分为模块是降低软件复杂度的有效方法 在Java项目中,我们通常会会把一个项目分拆为模块,这是为了降低软件复杂度. 例如:我们可以把一个大的项目氛围module-a, module-b, ...
- VS code 设置侧边栏字体大小
1.代码改写,进入默认安装的如下路径 C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\resources\app\out ...
- php链表笔记:链表的检测
<?php /** * Created by PhpStorm. * User: huizhou * Date: 2018/12/2 * Time: 11:48 */ /** * 链表的检测 * ...
- 滚动字幕标记<marquee></marquee>
<marquee>滚动内容</marquee> 常用属性: Direction : 滚动方向 取值 up, down left right width :滚动宽度 heigh ...
- day 42 02--CSS的继承性和层叠性
02--CSS的继承性和层叠性 本节目录 一 继承性 二 层叠性 三 层叠性权重相同处理 一 继承性 css有两大特性:继承性和层叠性 面向对象语言都会存在继承的概念,在面向对象语言中,继承的特点 ...
- spring retry 重试机制完整例子
public static Boolean vpmsRetryCoupon(final String userId) { // 构建重试模板实例 RetryTemplate retryTemplate ...
- java基础之二维数组不定义列数
有一种特殊的二维数组,它的行数确定,但是每行的列数不确定.这样的的数组实现方法:先创建制定行数,列数缺省的二维数组,然后对数组的每一行重新初始化.举例如下: package day5; //第二种定义 ...