zoukankan      html  css  js  c++  java
  • [CF585E]Marbles

    Description:

    给定一个序列 (a_i) ,每次可以交换相邻两个元素,求使序列变成若干个极大连续段,每个极大连续段内部的值相同且任意两个极大连续段的值互不相同。

    (nle 4 imes 10^5, a_ile 20)

    Solution:

    由于值域很小,启发我们从值域入手,考虑每一种颜色。

    (cnt[i][j]) 表示在只考虑颜色 (i)(j) 的情况下,把所以颜色 (i) 都移到所有颜色 (j) 的前面的步数,这个对每一个颜色用 ( ext{vector}) 存下出现的位置(从小到大),用 ({ m two pointers}) 扫一下即可求得 。

    考虑状压每一种颜色,二进制下为1表示这个位的颜色已经被安排好了。

    (dp[S]) 表示 (S) 的颜色已经安排好在序列的前面且两两不交的最小步数,那么转移就枚举一个不在 (S) 中的点 (i) ,把 (i) 放在考虑完的 (S) 的后面,那么产生的步数就是把 (S) 放在 (i) 的前面的步数,通过 (cnt[][i]) 可以求得。

    Code:

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <fstream>
    
    typedef long long LL;
    typedef unsigned long long uLL;
    
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define MP(x, y) std::make_pair(x, y)
    #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
    #define GO cerr << "GO" << endl;
    
    using namespace std;
    
    inline void proc_status()
    {
    	ifstream t("/proc/self/status");
    	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
    }
    
    template<class T> inline T read() 
    {
    	register T x(0);
    	register char c;
    	register int f(1);
    	while (!isdigit(c = getchar())) if (c == '-') f = -1;
    	while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
    	return x * f;
    }
    
    template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
    template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
    
    const int maxN = 4e5;
    const int maxM = 20;
    
    int n;
    vector<int> col[maxM + 1];
    LL cnt[maxM + 1][maxM + 1];
    LL dp[1 << maxM];
    
    void Input()
    {
    	n = read<int>();
    	for (int i = 1; i <= n; ++i)
    	{
    		int x = read<int>();
    		col[x].push_back(i);
    	}
    }
    
    void Init()
    {
    	for (int i = 1; i <= 20; ++i)
    		for (int j = 1; j <= 20; ++j)
    			if (i != j) 
    			{
    				if (!col[i].size() || !col[j].size()) continue;
    				int l = 0;
    				for (int k = 0; k < SZ(col[i]); ++k)
    				{
    					while (true)
    					{
    						if (l == SZ(col[j]) - 1 || col[j][l + 1] > col[i][k])
    							break;
    						l++;
    					}
    					if (col[j][l] < col[i][k])
    						cnt[i][j] += l + 1;
    				}
    			}
    }
    
    void Solve()
    {
    	memset(dp, 0x3f, sizeof dp);
    
    	dp[0] = 0;
    	for (int S = 0; S < 1 << maxM; ++S)
    	{
    		for (int i = 0; i < maxM; ++i)
    			if (!(S >> i & 1))
    			{
    				LL sum(0);
    				for (int j = 0; j < maxM; ++j)
    					if (S >> j & 1)
    						sum += cnt[j + 1][i + 1];
    				chkmin(dp[S | (1 << i)], dp[S] + sum);
    			}
    	}
    
    	cout << dp[(1 << maxM) - 1] << endl;
    }
    
    int main() 
    {
    #ifndef ONLINE_JUDGE
    	freopen("CF585E.in", "r", stdin);
    	freopen("CF585E.out", "w", stdout);
    #endif
    	Input();
    	Init();
    	Solve();
    	return 0;
    }
    
  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/cnyali-Tea/p/11530714.html
Copyright © 2011-2022 走看看