zoukankan      html  css  js  c++  java
  • GHOJ 666 筷子

    题目描述

      A先生有很多双筷子。确切的说应该是很多根,因为筷子的长度不一,很难判断出哪两根是一双的。这天,A先生家里来了K个客人,A先生留下他们吃晚饭。加上A先生,A夫人和他们的孩子小A,共K+3个人。每人需要用一双筷子。A先生只好清理了一下筷子,共N根,长度为T1,T2,T3,......,TN。现在他想用这些筷子组合成K+3双,使每双的筷子长度差的平方和最小。(怎么不是和最小??这要去问A先生了,呵呵)

     

    输入格式

      两行:

      第一行为两个用空格隔开的整数,表示N,K(1≤N≤100,0<K<50);

      第二行共有N个用空格隔开的整数,为Ti。每个整数为1-50之间的数。

    输出格式

      一行,如果凑不齐K+3双,输出-1,否则输出长度差平方和的最小值。

     

    输入样例

    10 1

    1 1 2 3 3 3 4 6 10 20

     

    输出样例

    5
     

    样例说明

      第一双 1 1

      第二双 2 3

      第三双 3 3

      第四双 4 6

    题解

      容易想到,我们设第$i$个人拥有筷子$c_{2i-1}$、$c_{2i}$,那么对于所有被选的筷子,一定有$c_{j} leqslant c_{j+1}$。

      我们对筷子长度进行排序,然后直接dp即可。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    #define MAX_N 100
    #define MAX_M 50
    
    using namespace std;
    
    int n, m;
    int a[MAX_N | 1];
    int dp[MAX_N | 1][MAX_M + 4];
    
    int main()
    {
        cin >> n >> m;
        m += 3;
        if(n < (m << 1)) return cout << -1, 0;
        for(register int i = 1; i <= n; ++i)
        {
            cin >> a[i];
        }
        sort(a + 1, a + n + 1);
        for(register int k = 1; k <= m; ++k)
        {
            dp[(k << 1) - 1][k] = 2000000000;
            for(register int i = k << 1; i <= n; ++i)
            {
                dp[i][k] = dp[i - 1][k];
                for(register int j = (k << 1) - 1; j < i; ++j)
                {
                    dp[i][k] = min(dp[i][k], dp[j - 1][k - 1] + (a[i] - a[j]) * (a[i] - a[j]));
                }
            }
        }
        cout << dp[n][m];
        return 0;
    }
    参考程序
  • 相关阅读:
    linux下动态链接库.so文件 静态链接库.a文件创建及使用
    matlab 自动阈值白平衡算法 程序可编译实现
    C++ 迭代器介绍 [转摘]
    C++ Primer 第三章 标准库类型vector+迭代器iterator 运算
    matlab灰度变彩色+白平衡算法实现
    我和奇葩的故事之失联第七天
    C++ Primer 第三章 标准库类型string运算
    OpenCV白平衡算法之灰度世界法(消除RGB受光照影响)
    查看网络情况netstat指令与动态监控top指令
    linux服务
  • 原文地址:https://www.cnblogs.com/kcn999/p/10885469.html
Copyright © 2011-2022 走看看