CF1342F Make It Ascending
CF1342F Make It Ascending
题目大意
给定一个长度为 n n n的序列 a a a,每次可以选择两个位置 i , j ( i ≠ j ) i,j(i\not=j) i,j(i=j),令 a j = a i + a j a_j=a_i+a_j aj=ai+aj并将 a i a_i ai从序列中删除
求将原序列变成严格单调上升序列的最少操作次数
n ≤ 15 n\le15 n≤15
题目相当于:求将序列 a a a划分成若干集合 S 1 , S 2 , ⋯ , S c S_1,S_2,\cdots,S_c S1,S2,⋯,Sc,集合之间有序,满足 S i S_i Si之和小于 S i + 1 S_{i+1} Si+1之和(即单调递增),且存在一个单调上升序列 p p p满足 p i ∈ S i p_i \in S_i pi∈Si,即我们最终会将 S i S_i Si所有其他元素累和到原序列位置为 p i p_i pi的元素上 求最多划分出多少集合
朴素的想法是将所有限制全部装进 D P DP DP里面,即设 f i , j , k f_{i,j,k} fi,j,k表示当前考虑了编号为 i i i的数集,最后一个划分出的集合对应的 p p p的最小值为 j j j,且总和为 k k k时,最多划分出多少集合
转移根据实际意义显然
这样复杂度太大了 因为我们把值域装了进去 考虑如何把值域去掉
由于若 k > k ′ k>k^{'} k>k′且 f i , j , k ≤ f i , j , k ′ f_{i,j,k} \le f_{i,j,k^{'}} fi,j,k≤fi,j,k′则前者显然无用
这说明对于相同的 f i , j , k f_{i,j,k} fi,j,k,仅有最小的 k k k有用
根据这一性质,我们尝试忽略无用状态,交换 D P DP DP的某一维度和值域
这意味着,我们设 f i , j , k f_{i,j,k} fi,j,k表示当处于上述意义下的 i , j i, j i,j以及集合个数为 k k k时,最后一个集合的和的最小值
转移即在 i i i这一维枚举子集,同时枚举 j , k j,k j,k
转移条件有三个:
- ∑ p ∈ S a p > f i , j , k \sum_{p \in S} a_p > f_{i,j,k} ∑p∈Sap>fi,j,k
- ∃ p ∈ S s.t. p > j \exists p \in S \text{s.t.} p >j ∃p∈Ss.t.p>j 设 p m i n p_{min} pmin为最小的这样的 p p p
- i ∩ S = ∅ i \cap S = \varnothing i∩S=∅
则 f i , j , k f_{i,j,k} fi,j,k可以转移到 f i ∪ S , p m i n , k + 1 f_{i \cup S,p_{min},k+1} fi∪S,pmin,k+1,并令后者对 ∑ p ∈ S a p \sum_{p \in S}a_p ∑p∈Sap取 m i n min min
容易发现 时间复杂度为 O ( 3 n n 2 ) \mathcal{O} (3^n n^2) O(3nn2)
由于不合法状态较多 故 ✓ \checkmark ✓
#include <bits/stdc++.h>
using namespace std;const int N = 16;
struct dat {int msk, num, pos;} tr[1 << N][N][N];
int T, n, a[N], ban[N], s[1 << N], f[1 << N][N][N];
vector <pair <int, int>> ans;
int find(int x) {int rnk = 1;for(int i = 1; i < x; i++) if(!ban[i]) rnk++;return rnk;
}
void calc(int msk, int num, int pos) {if(!msk) return;dat t = tr[msk][num][pos];calc(t.msk, t.num, t.pos);for(int i = 0; i < n; i++)if(msk - t.msk >> i & 1 && i != pos - 1)ans.push_back({i + 1, pos});
}
void solve() {cin >> n, ans.clear();for(int i = 0; i < n; i++) cin >> a[i];for(int i = 0; i < 1 << n; i++)for(int j = 0; j <= n; j++)for(int k = 0; k <= n; k++)f[i][j][k] = 1e9;f[0][0][0] = 0;for(int i = 1; i < 1 << n; i++)for(int j = 0; j < n; j++)if(i >> j & 1)s[i] = s[i - (1 << j)] + a[j];for(int i = 0; i < 1 << n; i++)for(int j = 0; j < n; j++)for(int k = 0; k < n; k++)if(f[i][j][k] < 1e9) {int C = (1 << n) - 1 - i;for(int S = C; S; S = (S - 1) & C)if(s[S] > f[i][j][k] && S >> k) {int nk = __builtin_ctz(S >> k << k) + 1;if(s[S] >= f[i + S][j + 1][nk]) continue;f[i + S][j + 1][nk] = s[S];tr[i + S][j + 1][nk] = {i, j, k};}}for(int num = n; num; num--)for(int pos = 0; pos <= n; pos++)if(f[(1 << n) - 1][num][pos] != 1e9) {calc((1 << n) - 1, num, pos);cout << ans.size() << endl;memset(ban, 0, sizeof(ban));for(auto it : ans) {cout << find(it.first) << " " << find(it.second) << endl;ban[it.first] = 1;}return;}
}
int main() {cin >> T;while(T--) solve();return 0;
}
CF1342F Make It Ascending相关推荐
- 一二三系列之状压DP——Max Correct Set(一)Neko Rules the Catniverse (Large Version)(二)Make It Ascending(三)
文章目录 一:CF1463F 二:CF1152F2 三:CF1342F 一:CF1463F Max Correct Set 有一个结论:以x+yx+yx+y为周期排列填充一定是不劣于最后的答案的 令p ...
- 我的收藏中的十大开源论坛
有许多用PHP,ASP.NET和Perl编写的免费开源论坛系统(公告板,留言板). 以下是我最喜欢的免费开源论坛收藏集的列表. 我只列出了具有详细文档和良好社区支持的论坛. PS此列表不按任何特定顺序 ...
- 【CF1342F】 Make It Ascending
题目 题目描述 You are given an array aa consisting of nn elements. You may apply several operations (possi ...
- pandas使用sort_values函数对dataframe的日期数据列进行排序(设置ascending参数进行正序或者倒序排序)
pandas使用sort_values函数对dataframe的日期数据列进行排序(设置ascending参数进行正序或者倒序排序) 目录
- seaborn可视化条形图并按照升序排序条形图进行可视化:Sort Bars in Barplot in Ascending Order in Python
seaborn可视化条形图并按照升序排序条形图进行可视化:Sort Bars in Barplot in Ascending Order in Python 目录
- C语言实现升序优先队列Ascending priority queue(附完整源码)
实现升序优先队列Ascending priority queue node结构体 升序优先队列Ascending priority queue完整源码(定义,实现,main函数测试) node结构体 ...
- 输入学生成绩,并按升序排列 Ascending.java
import java.util.Arrays; import java.util.Scanner; public class Ascending{ public static void main(S ...
- R语言使用order函数对dataframe数据进行排序、基于多个字段(变量)进行升序排序(ASCENDING)
R语言使用order函数对dataframe数据进行排序.基于多个字段(变量)进行升序排序(ASCENDING) 目录
- pandas使用read_csv函数读取csv数据、sort_index函数基于多层行索引对数据排序(设置ascending参数列表指定不同层行索引的排序方向)
pandas使用read_csv函数读取csv数据.index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引.sort_index函数基于多层行索引对数据排序(设置ascending ...
最新文章
- 关于加载Fashion MNIST数据集时可能会出现的问题
- 新口令范筹(Token Scope)- viewables:read
- 【Paper】论文中定义、定理、引理、证明分别的含义
- 【中级软考】白盒测试和黑盒测试
- python实现文件上传和下载_[Python] socket实现TFTP上传和下载
- Samba安装配置用于虚拟机共享文件_很详细
- Zookeeper 安装和配置---学习一
- java super是什么意思_java中Super到底是什么意思?必须举例说明!
- GridView控件RowDataBound事件中获取列字段值的几种途径
- 惠普第八代游戏家族产品重磅首发,搭载英特尔第十二代酷睿处理器
- trunk配置功能详解
- 浙大 PAT b1036
- [转载] Flask+Celery+Redis简单操作
- 网站结构优化的基本方法
- Linux进程控制与进程优先级
- Unity--使用反编译软件ILSpy查看dll中的代码
- mqtt测试工具(持续更新...)
- 从零开始的数模学习(7):插值方法(预测类模型)
- 基于元数据规则的大数据解决方案
- python窗口截图快捷键_python 自定义截图快捷键
热门文章
- android 非常好用的日期时间api Jota-Time(获取具体年、月、日、时、分、秒)
- SSM+mysql机票订购系统-计算机毕业设计源码07780
- Java高性能高并发实战之页面优化技术(五)
- MAC系统如何更换管理员用户
- 紫微圣人的程序员人生第4回 [原创IT小说]-撒粉必用无人机,保命全靠路由器
- Latex排版Algorithm之algorithmic,algorithmicx,algorithm2e
- 摄影基础知识——ISO
- Kubernetes存储之Rook的ceph搭建
- FL Studio步进音序器中的节奏怎么制作
- 地震预测与概率(转)