zoukankan      html  css  js  c++  java
  • UVALive 6088 Approximate Sorting 构造题

    题目链接:点击打开链接

    题意:

    给定一个n*n的01矩阵

    我们跑一下例子==

    4
    0111
    0000
    0100
    0110

      0123

    |____
    0|0111
    1|0000
    2|0100
    3|0110

    用0-n-1随便构造一个序列:

    如:1230

    我们计算1230的权值 :

    int ans = 0;

    对于个位0,我们查找第0行:0111,0前面的数有123, 则ans += a[0][1], ans+=a[0][2], ans+=a[0][3]

    对于十位3。我们查找第3行:0110。3前面的数有12, ans+=a[3][1], ans+=a[3][2]

    如此得到ans = 6

    问:

    构造一个这种序列使得ans最小,若有多个这种序列则输出序列字典序最小的。

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <map>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int Inf = 1e9;
    typedef long long ll;
    const int N = 18;
    const int S = 1 << N;
    int d[S], one[S];
    int w[N], n, mx;
    int out[N], dep;
    map<int, int> id;
    
    int dp(int s) {
    	if (~d[s])
    		return d[s];
    	d[s] = Inf;
    	int i, to, x = s;
    	while (x>0) {
    		to = (x&(x-1)) ^ x;
    		i = id[to];
    		d[s] = min(d[s], dp(s^(1<<i)) + one[w[i]&s]);
    		x = x^to;
    	}
    	return d[s];
    }
    void dfs(int dep, int cur, int g) {
    	if (dep == N) {
    		one[cur] = g;
    	} else {
    		dfs(dep+1, cur*2+1, g+1);
    		dfs(dep+1, cur*2, g);
    	}
    }
    void path(int s) {
    	if (s != 0) {
    		for (int i = 0; i < n; ++i)
    			if (s >> i & 1) {
    				if (dp(s^(1 << i)) + one[w[i]&s] == dp(s) ) {
    					out[dep++] = i;
    					path(s^(1 <<i));
    					return ;
    				}
    			}
    	}
    }
    char s[N];
    void work() {
    	memset(w, 0, sizeof w);
    	for (int i = 0; i < n; ++i) {
    		scanf("%s", s);
    		for (int j = 0; j < n; ++j)
    			if (s[j] == '1' && j != i)
    				w[j] |= 1 << i;
    	}
    	mx = (1 << n) - 1;
    	memset(d, -1, sizeof d);
    	d[0] = 0;
    	int ans = dp(mx);
    	dep = 0;
    	path(mx);
    	for (int i = 0; i < dep; ++i) {
    		if (i > 0)
    			putchar(' ');
    		printf("%d", out[i]);
    	}
    	puts("");
    	printf("%d
    ", ans);
    }
    int main() {
    	dfs(0, 0, 0);
    	for (int i = 0; i < N; ++i)
    		id[1 << i] = i;
    	while (~scanf("%d", &n)) {
    		if (0 == n)
    			break;
    		work();
    	}
    	return 0;
    }
    


  • 相关阅读:
    ABP 菜单 修改
    C# 过滤器
    RabbitMQ框架构建系列(三)——Net实现RabbitMQ之Producer
    RabbitMQ系列(二)RabbitMQ基础介绍
    RabbitMQ系列(一)AMPQ协议
    MVC 解读WebConfig
    MVC过滤器特性
    asp.net中使用JQueryEasyUI
    asp.net请求到响应的整个过程
    Redis的下载安装部署(Windows)
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5338141.html
Copyright © 2011-2022 走看看