• JZOJ 3166. 【GDOI2013模拟3】火星菌(DP)


    JZOJ 3166.【GDOI2013模拟3】火星菌

    题目

    Description

    科学家发现火星上有一种奇怪的细菌,每天产生的新细菌数量是 2 2 2的幂,因为每天新产生的细菌会在下一天产生两个新细菌,第一天只有一个细菌。因此,第一天有 1 1 1个细菌,第二天有 2 2 2个,第三天有 4 4 4个,。。。,第 k + 1 k+1 k+1天有 2 k 2^k 2k 个细菌。用 1 1 1 2 k 2^k 2k对这 2 k 2^k 2k个细菌进行编号,同时满足:

    k k k天的细菌的子孙分别是 ( 1 , 2 ) , ( 3 , 4 ) , ( 5 , 6 ) , 。 。 。 , ( 2 k − 1 , 2 k ) (1,2),(3,4),(5,6),。。。,(2^k-1,2^k) (1,2)(3,4)(5,6),(2k1,2k)

    k − 1 k-1 k1天的细菌的子孙分别是 ( 1 , 2 , 3 , 4 ) , ( 5 , 6 , 7 , 8 ) , 。 。 。 , ( 2 k − 3 , 2 k − 2 , 2 k − 1 , 2 k ) (1,2,3,4),(5,6,7,8),。。。,(2^k-3,2^k-2,2^k-1,2^k) (1,2,3,4)(5,6,7,8)(2k3,2k2,2k1,2k)

    k − 2 k-2 k2天的细菌的子孙分别是 ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ) , 。 。 。 , ( 2 k − 7 , 2 k − 6 , 2 k − 5 , 2 k − 4 , 2 k − 3 , 2 k − 2 , 2 k − 1 , 2 k ) (1,2,3,4,5,6,7,8),。。。,(2^k-7,2^k-6,2^k-5,2^k-4,2^k-3,2^k-2,2^k-1,2^k) (1,2,3,4,5,6,7,8)(2k7,2k6,2k5,2k4,2k3,2k2,2k1,2k)

    。。。

    2 2 2天的细菌的子孙分别是 ( 1 , 2 , 3 , . . . , 2 k − 1 ) , ( 2 k − 1 + 1 , 2 k − 1 + 2 , . . . , 2 k ) (1,2,3,..., 2^{k-1}),(2^{k-1}+1,2^{k-1}+2,...,2^k) (1,2,3,...,2k1)(2k1+1,2k1+2,...,2k)

    其中括号括起来的集合里面的元素是一个细菌的子孙,以上对第 k + 1 k+1 k+1天的 2 k 2^k 2k个细菌的编号方式满足:前面任何一天的任何一个细菌的子孙编号都是连续的数字。

    但编号方法不是唯一的,可能有很多种方法,现在给定任意两个编号 i i i j j j之间的权值 w [ i ] [ j ] w[i][j] w[i][j],要求找到 1 1 1 2 k 2^k 2k的一个排列 A 1 , A 2 , . . . . , A 2 k − 1 , A 2 k A_1,A_2,....,A_{2^k-1},A_{2^k} A1,A2,....,A2k1,A2k满足前面任何一天的细菌的子孙都对应着一段连续的数字,同时要求排列的权值 w [ A 1 ] [ A 2 ] + w [ A 2 ] [ A 3 ] + . . . . + w [ A 2 k − 1 ] [ A 2 k ] w[A_1][A_2]+w[A_2][A_3]+....+w[A_{2^k-1}][A_{2^k}] w[A1][A2]+w[A2][A3]+....+w[A2k1][A2k]最小。

    Input

    第一行输入一个整数 k ( 1 ≤ k ≤ 9 ) k(1≤k≤9) k(1k9)

    接下来 2 k 2^k 2k行,每行输入 2 k 2^k 2k个数,范围在 0 0 0 1 0 6 10^6 106之间,表示 w [ i ] [ j ] w[i][j] w[i][j]

    当然输入保证 w [ i ] [ j ] = w [ j ] [ i ] w[i][j]=w[j][i] w[i][j]=w[j][i] w [ i ] [ i ] = 0 w[i][i]=0 w[i][i]=0.

    Output

    输出一个数表示满足条件的 1 1 1 2 k 2^k 2k的排列的最小权值。

    Sample Input

    输入1:
    2
    0 7 2 1
    7 0 4 3
    2 4 0 5
    1 3 5 0

    输入2:
    3
    0 2 6 3 4 7 1 3
    2 0 7 10 9 1 3 6
    6 7 0 3 5 6 5 5
    3 10 3 0 9 8 9 7
    4 9 5 9 0 9 8 4
    7 1 6 8 9 0 8 7
    1 3 5 9 8 8 0 10
    3 6 5 7 4 7 10 0

    Sample Output

    输出1:
    13

    输出2:
    32

    Data Constraint

    100%的数据满足 1 ≤ k ≤ 9 1≤k≤9 1k9.

    Hint

    样例1 中满足条件的排列有 ( 1 , 2 , 3 , 4 ) 、 ( 1 , 2 , 4 , 3 ) 、 ( 2 , 1 , 3 , 4 ) 、 ( 2 , 1 , 4 , 3 ) 、 ( 3 , 4 , 1 , 2 ) 、 ( 3 , 4 , 2 , 1 ) 、 ( 4 , 3 , 1 , 2 ) 、 ( 4 , 3 , 2 , 1 ) (1,2,3,4)、(1,2,4,3)、(2,1,3,4)、(2,1,4,3)、(3,4,1,2)、(3,4,2,1)、(4,3,1,2)、(4,3,2,1) (1,2,3,4)(1,2,4,3)(2,1,3,4)(2,1,4,3)(3,4,1,2)(3,4,2,1)(4,3,1,2)(4,3,2,1)对应的权值分别为 16 、 15 、 14 、 13 、 13 、 15 、 14 、 16 16、15、14、13、13、15、14、16 1615141313151416,权值最小的排列为 ( 2 , 1 , 4 , 3 ) (2,1,4,3) (2,1,4,3) ( 3 , 4 , 1 , 2 ) (3,4,1,2) (3,4,1,2),都是 13 13 13.

    题解

    • 这道题目的描述太太太太太复杂了!!
    • 简化题面:
    • 建一棵满二叉数(类似一棵线段树),
    • 0 0 0层—— [ 1 , 2 k ] [1,2^k] [1,2k]
    • 1 1 1层—— [ 1 , 2 k − 1 ] , [ 2 k − 1 + 1 , 2 k ] [1,2^{k-1}],[2^{k-1}+1,2^k] [1,2k1][2k1+1,2k]
    • ……
    • k k k层—— 1 , 2 , 3 … … 2 k 1,2,3……2^k 1,2,32k
    • 每个节点有两个子树(类似线段树),允许把任何一个节点的左右子树进行交换,最后第 k k k层不一定是 1 − 2 k 1-2^k 12k升序排列,可能是乱序的。
    • 问经过这样的随意交换后,最小的第 k k k层的序列每相邻两个数的 w w w值之和。
    • 考虑用DP解决:
    • f [ i ] [ j ] f[i][j] f[i][j]为最后一层第 i i i个数为 j j j的最小值,转移不难想到:
      f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ i − 1 ] [ h ] ) f[i][j]=min(f[i][j],f[i-1][h]) f[i][j]=min(f[i][j],f[i1][h])
    • (其中 h h h是枚举的)
    • 这成为一个不易解决的问题, h h h的范围是多少?
    • 把整个序列想象成很多块,
    • 1 1 1个大小为 2 k 2^k 2k的块, 2 2 2个大小为 2 k − 1 2^{k-1} 2k1的块…… 2 k 2^k 2k个大小为 1 1 1的块,按从左到右的顺序分开。
    • 找到一个 p p p,使 i i i i − 1 i-1 i1不在同一个大小为 p p p的块中,最大化 p p p.( p p p一定是 2 2 2的幂数)
    • 接着看 j j j所在的大小为 p p p的块是第 x x x个,找到 x x x.
    • 那么若 x x x为奇数, h h h的范围就是第 x + 1 x+1 x+1个大小为 p p p的块的范围;
    • x x x为偶数, h h h的范围就是第 x − 1 x-1 x1个大小为 p p p的块的范围。
    • 举个例子:
    • 当前 i = 5 , j = 35 i=5,j=35 i=5j=35
    • 发现 i i i i − 1 i-1 i1在同一个大小为 8 8 8的块中 [ 1 , 8 ] [1,8] [1,8],不在同一个大小为 4 4 4的块中 [ 1 , 4 ] [1,4] [1,4] [ 5 , 8 ] [5,8] [5,8],则 p p p 4 4 4.
    • j j j在第 9 9 9个大小为 4 4 4的块中 [ 33 , 36 ] [33,36] [33,36],那么 h h h的范围就是 [ 37 , 40 ] [37,40] [37,40].
    • 先把题目大意理解清楚,题解多看几遍,自己画一画图,很快就会明白的!

    代码

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int e[10],w[520][520],f[520][520];
    int main()
    {
    	int n,i,j,k;
    	e[0]=1;
    	for(i=1;i<=9;i++) e[i]=e[i-1]*2;
    	scanf("%d",&n);
    	for(i=0;i<e[n];i++)
    		for(j=0;j<e[n];j++) scanf("%d",&w[i][j]);
    
    	for(i=0;i<e[n];i++) f[0][i]=0;
    	
    	for(i=1;i<e[n];i++)
    		for(j=0;j<e[n];j++)
    		{
    			f[i][j]=2147483647;
    			int l,r;
    			
    			for(k=n;k>=0;k--)
    			{
    				if(i/e[k]!=(i-1)/e[k])
    				{
    					int x=j/e[k];
    					x^=1;
    					l=x*e[k];
    					r=l+e[k]-1;
    					break;
    				}
    			}
    			
    			for(k=l;k<=r;k++) if(f[i-1][k]+w[j][k]<f[i][j]) f[i][j]=f[i-1][k]+w[j][k];
    		}
    		
    	int ans=2147483647;
    	for(i=0;i<e[n];i++) if(f[e[n]-1][i]<ans) ans=f[e[n]-1][i];
    	
    	printf("%d",ans);
    	return 0;
    }
    
    哈哈哈哈哈哈哈哈哈哈
  • 相关阅读:
    CSS实现元素居中原理解析
    Windows 下 Ionic 开发环境搭建
    JavaScript实现简单的双向数据绑定
    JavaScript之Promise对象
    前端工程师的进阶之路
    前端开发必备之chrome插件
    Javascript之Event Loop
    CentOS7 如何挂载网络设备
    mysql 全量备份以及增量备份
    zabbix 内网监控云服务器
  • 原文地址:https://www.cnblogs.com/LZA119/p/13910088.html
Copyright © 2020-2023  润新知