zoukankan      html  css  js  c++  java
  • 洛谷 P3943 星空

    题意简述

    有一个长度为n的01序列,有k个1
    每次可以将给定长度的子串取反,即0->1, 1->0
    求最少几次可以将整个序列都变为0

    题解思路

    差分+状压DP
    首先将原序列异或差分
    每消去一对1就是将1移到一起
    先用bfs预处理出每两个1移到一起的最小步数
    然后用状压DP来求总的最小步数

    代码

    #include <queue>
    #include <cstdio>
    const int INF = 0x3f3f3f3f;
    int n, k, m, x, xx, cnt, C, X;
    int b[50000], c[50000], s[50000];
    int dis[100][100], dp[1000000];
    bool a[50000], dft[50000], used[50000];
    std::queue < int > q;
    inline void _min(int& x, const int y) {x = x > y ? y : x; }
    int main()
    {
    	scanf("%d%d%d", &n, &k, &m);
    	for (register int i = 1; i <= k; ++i) scanf("%d", &x), a[x] = 1;
    	for (register int i = 1; i <= n + 1; ++i)
    	{
    		dft[i] = a[i - 1] ^ a[i];
    		if (dft[i]) c[++cnt] = i;
    	}
    	for (register int i = 1; i <= m; ++i) scanf("%d", &b[i]);
    	for (register int i = 1; i <= cnt; ++i)
    	{
    		for (register int j = 1; j <= n + 1; ++j) s[j] = used[j] = 0;
    		used[c[i]] = 1;
    		q.push(c[i]);
    		while (!q.empty())
    		{
    			x = q.front();
    			q.pop();
    			for (register int j = 1; j <= m; ++j)
    			{
    				xx = x + b[j];
    				if (xx <= n + 1 && !used[xx])
    				{
    					s[xx] = s[x] + 1;
    					used[xx] = 1;
    					q.push(xx);
    				}
    				xx = x - b[j];
    				if (xx > 0 && !used[xx])
    				{
    					s[xx] = s[x] + 1;
    					used[xx] = 1;
    					q.push(xx);
    				}
    			}
    		}
    		for (register int j = 1; j <= cnt; ++j) dis[i][j] = s[c[j]];
    	}
    	C = 1 << cnt;
    	for (register int i = 1; i < C; ++i) dp[i] = INF;
    	for (register int i = 0; i < C; ++i)
    	{
    		x = 0; X = 1;
    		while (X & i) X *= 2, ++x;
    		for (register int j = x + 1, J = 1 << j; j <= cnt; ++j, J *= 2)
    			if (!(J & i) && dis[x + 1][j + 1])
    				_min(dp[i | X | J], dp[i] + dis[x + 1][j + 1]);
    	}
    	printf("%d
    ", dp[C - 1]);
    }
    
  • 相关阅读:
    WinForm控件之【DateTimePicker】
    WinForm控件之【ComboBox】
    WinForm控件之【CheckedListBox】
    第五章学习小结
    第四章学习小结
    第三章学习小结
    第二章学习小结
    iOS
    iOS
    iOS
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9839184.html
Copyright © 2011-2022 走看看