E. Marbles 状压dp
这个是一个状压dp
题目大意是:给你一个数组,数组的数在1到20之间,有一个操作就是交换相邻的两个数,问 让所有相同的数相邻的最小操作次数
dp[s] 表示s状态下的操作次数,w[i][j] 表示 i 前面 j 的个数,c[i] 表示一开始使 i 放到最前面的最小操作次数。
val[s][i] 表示在s状态下,将 i 放到前面的操作次数。
那么dp[tmp]=min(dp[tmp],dp[s]+val[s][j])
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 4e5 + ;
typedef long long ll;
vector<int>num;
ll dp[ << ], c[];
ll w[][], val[ << ][];
int vis[], b[], a[maxn], sum[];
bool vit[]; void judge(int x) {
num.clear();
for (int i = ; x; i++) {
if (x & ) num.push_back(i);
x >>= ;
}
} int main() {
int n, len = ;
scanf("%d", &n);
for (int i = ; i <= n; i++) {
scanf("%d", &a[i]);
if (!vit[a[i]]) b[++len] = a[i];
vit[a[i]] = ;
}
sort(b + , b + + len);
for (int i = ; i <= n; i++) a[i] = lower_bound(b + , b + + len, a[i]) - b;
for (int i = ; i <= n; i++) {
sum[a[i]]++;
for (int j = ; j <= len; j++) {
if (j == a[i]) continue;
w[a[i]][j] += sum[j];
}
}
memset(dp, inf64, sizeof(dp));
for (int i = ; i <= n; i++) {
c[a[i]] += i - - vis[a[i]];
vis[a[i]]++;
}
for (int i = ; i <= len; i++) dp[ << (i - )] = c[i];
for (int i = ; i < ( << len); i++) {
judge(i);
for (int j = ; j <= len; j++) {
ll x = c[j];
int tmp = << (j - );
if ((tmp | i) == i) continue;
for (int k = ; k < num.size(); k++) x -= w[j][num[k]];
val[i][j] = x;
}
}
for (int i = ; i < ( << len); i++) {
for (int j = ; j <= len; j++) {
int tmp1 = << (j - );
if ((tmp1 | i) == i) continue;
if (dp[i] >= inf64) continue;
tmp1 |= i;
dp[tmp1] = min(dp[tmp1], dp[i] + val[i][j]);
}
}
printf("%lld\n", dp[( << len) - ]);
return ;
}
E. Marbles 状压dp的更多相关文章
- codeforces#1215E. Marbles(状压DP)
题目大意:给出一个由N个整数组成的序列,通过每次交换相邻的两个数,使这个序列的每个相同的数都相邻.求最小的交换次数. 比如给出序列:1 2 3 2 1 ,那么最终序列应该是 1 1 2 2 3 ,最小 ...
- Codeforces Round #585 (Div. 2) E. Marbles(状压dp)
题意:给你一个长度为n的序列 问你需要多少次两两交换 可以让相同的数字在一个区间段 思路:我们可以预处理一个数组cnt[i][j]表示把i放到j前面需要交换多少次 然后二进制枚举后 每次选择一个为1的 ...
- Codeforces Round #585 (Div. 2) E. Marbles (状压DP),BZOJ大理石(同一道题)题解
题意 林老师是一位大理石收藏家,他在家里收藏了n块各种颜色的大理石,第i块大理石的颜色为ai.但是林老师觉得这些石头在家里随意摆放太过凌乱,他希望把所有颜色相同的石头放在一起.换句话说,林老师需要对现 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
随机推荐
- Nginx如何来配置隐藏入口文件index.php(代码)
Nginx配置文件里放入这段代码 server { location / { index index.php index.html index.htm l.php; autoindex on; if ...
- AJ学IOS(43)之网易彩票底部自定义TabBar实现切换
AJ分享,必须精品 效果: 代码: NYTabBarController // // NYTabBarController.m // 彩票lottery // // Created by apple ...
- JS 的基础概念
本篇文章主要讲述js的基础知识! 首先,我们要明白什么是JS,JS就是 javascript 的简称,是一种轻量级,弱类型的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能, ...
- 数值计算方法实验之Lagrange 多项式插值 (Python 代码)
一.实验目的 在已知f(x),x∈[a,b]的表达式,但函数值不便计算,或不知f(x),x∈[a,b]而又需要给出其在[a,b]上的值时,按插值原则f(xi)= yi(i= 0,1…….,n)求出简单 ...
- 理解java容器底层原理--手动实现ArrayList
为了照顾初学者,我分几分版本发出来 版本一:基础版本 实现对象创建.元素添加.重新toString() 方法 package com.xzlf.collection; /** * 自定义一个Array ...
- Thymeleaf入门入门入门入门入门入门入门入门入门入门入门
Thymeleaf 官网部分翻译:反正就是各种好 Thymeleaf是用来开发Web和独立环境项目的服务器端的Java模版引擎 Spring官方支持的服务的渲染模板中,并不包含jsp.而是Thymel ...
- PHP扩展Swoole的代码重载机制
大家都知道Swoole的性能在PHP界还算不错,同样都是PHP为什么呢,我专门研究了下. 几个概念: 1) sapi:可以简单的理解为php引擎对外的一个统一接口,使得php可以和外部程序进行交互 ...
- 小程序里json字符串转json对象需注意的地方
一.JSON字符串转换为JSON对象 要使用上面的str1,必须使用下面的方法先转化为JSON对象: //由JSON字符串转换为JSON对象 var obj = eval('(' + str + ') ...
- java学习(第三篇)String类
一.创建一个字符串 1.String(char a[]):用一个字符数组a创建一个string类型 char a[]= {'h','e','l','l','o'}; String s=new Stri ...
- Spring Security OAuth2 笔记(一)
关于 refresh_token refresh_token 主要是用来在 access_token 快要过期的时候,对 access_token 进行一个刷新,生成一个新的 access_token ...