zoukankan      html  css  js  c++  java
  • hihocoder #1170 机器人 && 编程之美2015复赛

    题意:

    时间限制:2000ms
    单点时限:1000ms
    内存限制:256MB

    描写叙述

    小冰的N个机器人兄弟排成一列,每一个机器人有一个颜色。

    如今小冰想让同一颜色的机器人聚在一起。即随意两个同颜色的机器人之间没有其它颜色的的机器人。

    如果随意相邻的两个机器人能够交换位置。请问最少须要多少次交换?

    输入

    第一行为一个整数T。为数据组数,之后每组数据两行。

    第一行为N和K,表示机器人的个数与颜色的总数。

    接下来一行N个数,第i个数表示第i个机器人的颜色,取值范围为1到K。

    输出

    对于每组数据输出一行,形如"Case #X: Y"。X为数据组数,从1開始。Y为最少的交换步数。

    数据范围

    1 ≤ T ≤ 20

    1 ≤ N ≤ 105

    小数据

    1 ≤ K ≤ 3

    大数据

    1 ≤ K ≤ 16

    题解:

    1.状态压缩dp,dp[11001]表示1,2,5这三种机器人已经达到要求(而且1,2,5排在3,4号机器人的前面)所须要的最

    少步数

    2.举个样例说明:1,2,3,4,5这五种机器人。当dp[10001]转移到dp[11001]。要想让2号达到要求。而且已知1,5号机器人

    已经达到要求,就须要让2,3。4号机器人通过交换位置使得,2号机器人排在一起,且处于3。4号机器人的前边

    3.达到这个目标。须要知道:逆序数对==通过交换最少的次数达到'有序'

    4.预处理i号机器人(范围[1,k])到j号机器人(范围[1,k])所产生的逆序对数pre[i][j]

    5.最后达到3的目标。pre[2][3] + pre[2][4]就是将2号机器人换到3,4号机器人前方所须要的步数

    总结:

    1.開始想用贪心写。写完之后才发现错了

    2.看到网上说状态压缩,事实上就是暴力,想了好多天依然没有想出来

    3.看到逆序对数==最少交换步数才差点儿相同想出来怎么做的

    4.感觉还须要努力。加强全面思考问题的能力

    5.近期在学习图像处理,opencv,进度太慢被老师说了,须要提高工作效率!

    6.项目这样的事情还是要快。快,快,不能像ACM享受慢慢思考并弄懂问题的快乐。也可能与平时效率低下不愿面对自

    己的问题有关

    7.总之,不同的科目有不同的学习方法,可是无论什么都须要提高效率。而且都要弄懂原理

    8.不纠结于细节,高速找到自己须要学习的目标。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    typedef long long LL;
    #define MAXN 100005
    #define INF 0x3f3f3f3f3f3f3f3f
    #define MAXM 16
    #define MAXP 65536
    int n,m,pre[MAXM][MAXM];
    LL dp[MAXP];
    vector<int>vec[MAXM];
    int main()
    {
        int _,cur;
        for(int kcas = scanf("%d",&_);kcas <= _;kcas++)
        {
            scanf("%d%d",&n,&m);
            for(int i = 0;i < m;i++)vec[i].clear();
            for(int i = 0;i < n;i++)
            {
                scanf("%d",&cur);
                vec[cur - 1].push_back(i);
            }
            memset(pre,0,sizeof(pre));
            for(int i = 0;i < m;i++)
                for(int j = 0;j < m;j++)if(i != j)
                    for(int u = 0,v = 0;u < vec[i].size();u++)
                    {
                        while(v < vec[j].size() && vec[i][u] > vec[j][v])
                            v++;
                        pre[i][j] += v;
                    }
            memset(dp,0x3f,sizeof(dp));
            dp[0] = 0;
            int cnt = 1 << m;
            for(int i = 0;i < cnt;i++)
            {
                for(int j = 0;j < m;j++)if(!(i >> j & 1))
                {
                    LL num = 0;
                    for(int k = 0;k < m;k++)if(!(i >> k & 1) && k != j)
                        num += pre[j][k];
                    dp[i | (1 << j)] = min(dp[i | (1 << j)],dp[i] + num);
                }
            }
            printf("Case #%d: %lld
    ",kcas,dp[(1 << m) - 1]);
        }
    }
    


  • 相关阅读:
    GoldenGate配置(一)之单向复制配置
    Qt4.8.6+mingw+Qgis2.4.0基于QGis的二次开发
    Linux用户及用户组设置
    HDU1013_Digital Roots【大数】【水题】
    随意一条查询sql转换为查询结果集相应的数目
    对文件地址的几种概念的理解
    2014-10深圳全球架构师峰会
    有沃更精彩,沃课堂理想的移动学习平台
    自己动手写CPU之第九阶段(8)——MIPS32中的LL、SC指令说明
    Inno Setup入门(二)——修改安装过程中的图片
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5409509.html
Copyright © 2011-2022 走看看