zoukankan      html  css  js  c++  java
  • UVA 10271 Chopsticks

    大意: 

    在中国,众通常用一双筷子吃饭。但是L先生与众不同:他用三支筷子吃饭。其中的一支长筷子用来叉取大块的食物,而剩下两支用作普通筷子。两支普通筷子的长度应尽可能的接近,而长的那支只要是三支中最长的就可以了。对于一幅筷子的长度ABCABC),定义函数(AB2为这副筷子的“难用度”。

    L先生邀请K个人参加他的生日聚会,并且想将他用筷子的方法介绍给其他人。他需要准备K+8副这样的筷子(给他自己、妻子、儿子、女儿、父亲、母亲、岳父、岳母以及K名客人)。但是L先生的筷子有很多不同的长度!给出所有筷子的长度,他需要找到一种组合K+8副筷子的方法,使得难用度的总和最小。

    这道题我们先降序排序,然后再用动态规划去解决,为什么要降序排序呢?因为这三只筷子里有最长的一只,如果我们按已给的递增顺序递推,无法保证存在最长筷子,相反降序递推,因为这组数的最大值不可能成为一双筷子里的一只,只能是作为第三只筷子存在(或者不选)因此就避免了上面的问题。当然实现起来就不用排序了,因为题中已经给了递增顺序,倒过来就行了。

    代码如下:

    #include<stdio.h>
    #define MAXN 5000+10
    #define MAXN1 1000+10
    int a[MAXN], f[MAXN][MAXN1] = {0};
    int T, n, k, i, j;
    void solve()
    {
        for(i = 1; i <= n; i ++)
        {
            for(j = 1; j*3 <= i && j <= k+8; j ++)
            {
                f[i][j] = f[i-2][j-1]  + (a[i-1]-a[i])*(a[i-1]-a[i]);
                if(3*j < i && f[i][j] > f[i-1][j])
                    f[i][j] = f[i-1][j];
            }
        }
        printf("%d\n",f[n][k+8]);
    }
    void input()
    {
        while(~scanf("%d", &T))
        while(T --)
        {
            scanf("%d%d",&k, &n);
            for(int i = n; i; i --)
                scanf("%d",&a[i]);
            solve();
        }
    }
    int main()
    {
        input();
        return 0;
    }

     

  • 相关阅读:
    java performance
    C# and Java: Comparing Programming Languages
    MYSQL blogs and articles
    网络基本功系列:细说网络那些事儿
    Spark 优化器 ML的论文
    逻辑回归
    MapReduce
    Spark
    Set-Theory-and-Logic
    k-means
  • 原文地址:https://www.cnblogs.com/yuzhaoxin/p/2469133.html
Copyright © 2011-2022 走看看