• 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 配置Apache 、PHP
    SQL Server DML(SELECT)常见用法(二)
    SQL Server DML(UPDATE、INSERT、DELETE)常见用法(一)
    PropertyGrid—添加EventTab
    PropertyGrid—添加属性Tab
    PropertyGrid—默认属性,默认事件,属性默认值
    PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框
    PropertyGrid--为复杂属性提供编辑功能
    PropertyGrid--基本功能
    Intellij IDEA使用(一)项目模板类型
  • 原文地址:https://www.cnblogs.com/kcn999/p/10885469.html
Copyright © 2020-2023  润新知