• 九度oj 题目1452:搬寝室


    题目描述:

    搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了.看着寝室里的n件物品,xhd开始发呆,因为n是一个小于2000的整数,实在是太多了,于是xhd决定随便搬2*k件过去就行了.但还是会很累,因为2*k也不小是一个不大于n的整数.幸运的是xhd根据多年的搬东西的经验发现每搬一次的疲劳度是和左右手的物品的重量差的平方成正比(这里补充一句,xhd每次搬两件东西,左手一件右手一件).例如xhd左手拿重量为3的物品,右手拿重量为6的物品,则他搬完这次的疲劳度为(6-3)^2 = 9.现在可怜的xhd希望知道搬完这2*k件物品后的最佳状态是怎样的(也就是最低的疲劳度),请告诉他吧。

    输入:

    每组输入数据有两行,第一行有两个数n,k(2<=2*k<=n<2000).第二行有n个整数分别表示n件物品的重量(重量是一个小于2^15的正整数).

    输出:

    对应每组输入数据,输出数据只有一个表示他的最少的疲劳度,每个一行.

    样例输入:
    2 1
    1 3
    样例输出:
    4

    这个题一开始就觉得是用动态规划来做。但到底怎么样去使用,还是没有想出来。看了看别人的代码
    dp[n][k] 表示从前n个物品中选出2*k个物品的最小疲劳度
    若先对物品进行排序,发现相邻的两个肯定是差最小的,故对第i件物品,若不选第i件物品
    则dp[i][j] = dp[i-1][j] 前提是2*j <= i-1
    否则若选则第i件物品,则与它的差最小的则是第i-1件物品,那么第i-1件物品也应被选择
    dp[i][j] = dp[i-2][j-1] + (w[i]-w[i-1])*(w[i]-w[i-1])
    另外就是初始化的问题,这个是个令人头疼的问题
    代码如下
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
     
    int n, k;
    int w[2020];
     
    int cmp(int a, int b) {
        return a < b;
    }
     
    int dp[2010][1020];
    int main(int argc, char const *argv[])
    {
        while(scanf("%d %d",&n,&k) != EOF) {
            for(int i = 1; i <= n; i++) {
                scanf("%d",&w[i]);
            }
            sort(w+1, w+1+n, cmp);
            memset(dp, -1, sizeof(dp));
            dp[2][1] = (w[2]-w[1])*(w[2]-w[1]);
            for(int i = 1; i <= n; i++) {
                dp[i][0] = 0;
            }
            for(int i = 3; i <= n; i++) {
                for(int j = 1; j<= k && 2*j <=i; j++) {
                    if(dp[i-1][j] == -1) {
                        dp[i][j] = dp[i-2][j-1] + (w[i]-w[i-1])*(w[i]-w[i-1]);
                    }
                    else {
                        dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + (w[i]-w[i-1])*(w[i]-w[i-1]));
                    }
                     
                    //printf("%d ",dp[i][j]);
                }
            //  puts("");
            }
            printf("%d
    ",dp[n][k]);
        }
        return 0;
    }

    一开始的代码如下

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <iostream>
     6 using namespace std;
     7  
     8 int n, k;
     9 int w[2020];
    10  
    11 int cmp(int a, int b) {
    12     return a < b;
    13 }
    14  
    15 int dp[2010][1020];
    16 int main(int argc, char const *argv[])
    17 {
    18     while(scanf("%d %d",&n,&k) != EOF) {
    19         for(int i = 1; i <= n; i++) {
    20             scanf("%d",&w[i]);
    21         }
    22         sort(w, w+n, cmp);
    23         memset(dp, -1, sizeof(dp));
    24         dp[2][1] = (w[2]-w[1])*(w[2]-w[1]);
    25         for(int i = 1; i <= n; i++) {
    26             dp[i][0] = 0;
    27         }
    28         for(int i = 3; i <= n; i++) {
    29             for(int j = 1; j<= k && 2*j <=i; j++) {
    30                 if(dp[i-1][j] == -1) {
    31                     dp[i][j] = dp[i-2][j-1] + (w[i]-w[i-1])*(w[i]-w[i-1]);
    32                 }
    33                 else {
    34                     dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + (w[i]-w[i-1])*(w[i]-w[i-1]));
    35                 }
    36                  
    37                 //printf("%d ",dp[i][j]);
    38             }
    39         //  puts("");
    40         }
    41         printf("%d
    ",dp[n][k]);
    42     }
    43     return 0;
    44 }

    第22行有错误,因为w下标从1开始,所以排序时你的下标不能从0开始

  • 相关阅读:
    【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截
    倪光南:保护科技人员知识产权是提升企业创新的关键(柳传志,杨元庆没有投入资金和技术,却占了大量股份,在全世界都非常少见)
    凡是能导到线上的都已经尝试过了,现在转化用户成本非常高,到了强者恒强的时代
    MIPS 指令集将在近期开源,RISC-V 阵营慌吗?
    QmlWinExtras
    用css解决Unigui在IE系列浏览器中字体变小的问题(设置UniServeModule的customcss属性)
    uni-app
    .net core consul grpc--系统服务RPC实现通信(一)
    系统间通信——RPC架构设计
    程序是由数据结构属于静态的部分和算法的调用为动态部分构成
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5873864.html
Copyright © 2020-2023  润新知