M - Little Pony and Harmony Chest 状压dp
M - Little Pony and Harmony Chest
怎么感觉自己越来越傻了,都知道状态的定义了还没有推出转移方程。
首先这个a的范围是0~30 这里可以推出 b数组的范围 0~60
原因很简单,因为这个要求abs(b-a)) 尽量小,所以如果b>=60 那还不如用1 ,因为1 的数量是没有限制的,
当 b>60 abs(b-a)>30 所以相比 b>60 b==1 更优。
然后我们对质数进行状压,为什么要对质数进行状压呢,因为质数两两互质,而且每一个数都是由若干个质数组成。
所以我们可以用质数来对状态进行筛选。
因为b的范围是从1到58(如果要选59,则也可以选1),所以我们要打个表,来表示他是由哪些素数组成的。
为什么要这样呢,因为这样可以就可以快速判断出之前的状态是不是和这个有冲突(就是有没有相同的质数)
知道这些就差不多了,这个题目利用状压位运算来判断一个两两之间有没有公约数,方法很巧妙。
具体:
dp[i][s] 表示到第 i 个位置,之前的状态为 s 的最小代价,
初始化 dp[0][0]=0,其他都是不合理的状态,所以初始化为inf
首先枚举位置,其次枚举状态,然后在枚举这个位置所有可能的数。
路径的输出就是记录这个状态的放的数,和这个状态之前的状态,一个是记录状态一个是记录数。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ;
typedef long long ll;
ll dp[][<<];
int is[][<<];
int pre[][<<];
int p[maxn], isp[maxn], m;
void init()
{
memset(p, , sizeof(p));
for (int i = ; i <= ; i++) p[i] = ;
for(int i=;i*i<=;i++)
{
if(p[i])
{
for(int j=i*i;j<=;j+=i)
{
p[j] = ;
}
}
}
m = ;
for(int i=;i<=;i++) if (p[i]) isp[++m] = i;
}
int sta[], a[];
vector<int>e;
int main()
{
int n; init();
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
if (i%isp[j] == ) sta[i] |= ( << (j - ));//sta 数组表示选i这个数的限制条件,这个要好好理解。
}
}
memset(pre, -, sizeof(pre));
memset(dp, inf64, sizeof(dp));
dp[][] = ;//这个dp定义的是到第i个位置,数的状态为s的代价,
//如果dp == inf 说明是不合理的状态,因为如果是在0这个位置,所以当没有数的状态就是合理的而且代价==0
for(int i=;i<n;i++)//这个从0 开始是因为每次第i个更新第i+1个
{
for(int j=;j<(<<);j++)
{
if (dp[i][j] == inf64) continue;
for(int k=;k<=;k++)
{
if (sta[k] & j) continue;
int tmp = sta[k] | j;
if (dp[i + ][tmp] > dp[i][j] + abs(a[i+] - k))
{
dp[i + ][tmp] = dp[i][j] + abs(a[i+] - k);
is[i + ][tmp] = k;
pre[i + ][tmp] = j;
}
}
}
}
int ans=inf, id=;
for(int i=;i<(<<);i++)
{
if(dp[n][i]<ans)
{
ans = dp[n][i];
id = i;
}
}
for(int i=n;i>=;i--)
{
e.push_back(is[i][id]);
id = pre[i][id];
}
for (int i = e.size() - ; i >= ; i--) printf("%d ", e[i]);
printf("\n");
return ;
}
状压dp
这个题目我现在做感觉不是很简单,之前已经写过一次了,今天又写了一次还是感觉有点迷糊。
明确dp的定义dp[s][i]表示状态为s 上一个节点是i的最小代价。
路径的输出就是记录这一个点这个状态选择的值,再记录上一个点的状态。
根据这个dp定义的状态可以知道要枚举状态和点,先枚举点再枚举每一个点可能的状态,
最后枚举这个点的所有可能性。
先枚举状态不是很好写。
M - Little Pony and Harmony Chest 状压dp的更多相关文章
- Codeforces Round #259 (Div. 2) D. Little Pony and Harmony Chest 状压DP
D. Little Pony and Harmony Chest Princess Twilight went to Celestia and Luna's old castle to resea ...
- CF453B Little Pony and Harmony Chest (状压DP)
CF453B CF454D Codeforces Round #259 (Div. 2) D Codeforces Round #259 (Div. 1) B D. Little Pony and H ...
- Codeforces 453B Little Pony and Harmony Chest:状压dp【记录转移路径】
题目链接:http://codeforces.com/problemset/problem/453/B 题意: 给你一个长度为n的数列a,让你构造一个长度为n的数列b. 在保证b中任意两数gcd都为1 ...
- codeforces 454 D. Little Pony and Harmony Chest(状压dp)
题目链接:http://codeforces.com/contest/454/problem/D 题意:给定一个序列a, 求一序列b,要求∑|ai−bi|最小.并且b中任意两数的最大公约数为1. 题解 ...
- [CF453B]Little Pony and Harmony Chest
[CF453B]Little Pony and Harmony Chest 题目大意: 给你一个长度为\(n(n\le100)\)的正整数序列\(A(A_i\le30)\),求一个正整数序列\(B\) ...
- Codeforces 454D - Little Pony and Harmony Chest
454D - Little Pony and Harmony Chest 思路: 状压dp,由于1的时候肯定满足题意,而ai最大是30,所以只要大于等于59都可以用1替换,所以答案在1到59之间 然后 ...
- CF 435B Little Pony and Harmony Chest
Little Pony and Harmony Chest 题解: 因为 1 <= ai <= 30 所以 1 <= bi <= 58, 因为 59 和 1 等效, 所以不需 ...
- Codeforces 4538 (状态压缩dp)Little Pony and Harmony Chest
Little Pony and Harmony Chest 经典状态压缩dp #include <cstdio> #include <cstring> #include < ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
随机推荐
- 基于linux或windows的c/s的循环服务器求一元二次方程的根
在linux和windows上实现 c/s模式 socket循环服务器求解一元二次方程的根 ax^2+bx+c=0 根据上式,客户端发送a,b,c给服务器,返回求解的根 暂未考虑非法数据等问题 lin ...
- 【Java】【设计模式 Design Pattern】单例模式 Singleton
什么是设计模式? 设计模式是在大量的实践中总结和理论化之后的最佳的类设计结构,编程风格,和解决问题的方式 设计模式已经帮助我们想好了所有可能的设计问题,总结在这些各种各样的设计模式当中,也成为GOF2 ...
- 用Python画的,5 种非传统的可视化技术,超炫酷的动态图
数据可以帮助我们描述这个世界.阐释自己的想法和展示自己的成果,但如果只有单调乏味的文本和数字,我们却往往能难抓住观众的眼球.而很多时候,一张漂亮的可视化图表就足以胜过千言万语.本文将介绍 5 种基于 ...
- 腾讯推出超强少样本目标检测算法,公开千类少样本检测训练集FSOD | CVPR 2020
论文提出了新的少样本目标检测算法,创新点包括Attention-RPN.多关系检测器以及对比训练策略,另外还构建了包含1000类的少样本检测数据集FSOD,在FSOD上训练得到的论文模型能够直接迁移到 ...
- 9. 弹出键盘挡住input
1.) react 中 <input className="inp3" placeholder="密码" type="password" ...
- Windows 上安装msql库安装(基于8.0.19免安装版)
一.进入官网进行下载mysql程序包: https://dev.mysql.com/downloads/mysql/ 二.解压缩 解压文件夹到指定目录,我放在 D:\mysql-8.0.19-winx ...
- EF-三种映射
更改实体的类名称,字段名称,来映射表名称,表字段. 1,用EF自带的特性方式: 直接加上特性,更新对应的类名,字段名以及引用类,字段名的相关地方 2,参考NHibernate建立一个EF自带的映射 ...
- C#获取文件夹内文件包括子文件(递归)实例
这个在我工作上,写了一次工具项目,用上的. static ArrayList FileList = new ArrayList();//这个必须写在方法外, static ArrayList GetA ...
- http的长连接与端连接
长连接的定义: HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...
- NTSTATUS code 和 Windows 系统错误码 的对应关系
出处:https://github.com/dokan-dev/dokany/blob/master/dokan/ntstatus.i case EPT_S_CANT_CREATE: return E ...