zoukankan      html  css  js  c++  java
  • 搬东西 dp

    搬东西

    现有n个扁担以及一辆货车,扁担一次挑两个货物,货车可以装K个货物,货车只能运送一次货物。

    现在qwb要把总共2n+k个货物搬到某个地方。现在qwb想选K个货物让货车先运走,然后剩下的2n个货物由他自己用扁担云过去,但是两个货物重量不均匀的话,会使得qwb感到很难受,每次会造成image.png的疲劳值,wi和wj是每次选的两个货物的重量,qwb想要n次运送后,使得image.png疲劳值的和最小。

    第一行两个整数 n和k (2 ≤ n ≤ 100,000),(1≤ k≤ 20).

    第二行2n+k个, w1, w2, ..., w2n+k, wi是每个货物的重量 (1 ≤ wi ≤ 1,000,000,000).

    输出一行,疲劳值的最小值。

    input

    3 2 

    1 3 4 6 3 4 100 200

    output

    5

    这个题目是一个dp,开始没有意识到,通过这个题,我感觉我太依赖别人了,这样不太好。

    dp[i][j] 表示前面 i 个物品,选出来 j 个 的最小疲劳值。

    如果已经选出来 2*n 个物品,怎么算疲劳值最小,就应该是 排序,相邻的放在一起就是疲劳值最小的。

    如果 i-j 是奇数,就是说那就是-  如果是偶数就是+

    所以可以得到转移方程 dp[i][j]=min(dp[i-1][j]+(j-i)%2==1?-a[i]:+a[i],dp[i-1][j-1])

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #include <string>
    #include <vector>
    #include <map>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 3e5 + 10;
    typedef long long ll;
    ll dp[maxn][30];
    ll w[maxn];
    
    int main()
    {
        int n, k;
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= 2*n+k; i++) scanf("%lld", &w[i]);
        sort(w + 1, w + 1 + 2*n+k);
        for(int i=1;i<=2*n+k;i++)
        {
            for(int j=0;j<=k;j++)
            {
                if (j == 0) dp[i][j] = dp[i - 1][j] + (i % 2 == 1 ? -w[i] : w[i]);
                else dp[i][j] = min(dp[i - 1][j] + ((i - j) % 2 == 1 ? -w[i] : w[i]), dp[i - 1][j - 1]);
            }
        }
        printf("%lld
    ", dp[2*n+k][k]);
        return 0;
    }
    View Code
  • 相关阅读:
    GIT学习实践笔记
    ubuntu 安装pygit2
    强化vim打造python的IDE
    Python Django学习和实践
    浏览器调试工具网页性能分析中的使用
    公司发版shell脚本重构
    Nightwatch+gulp
    Git
    JavaScript Unit Test with Qunit
    Unit Test Mocking Framework
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11252749.html
Copyright © 2011-2022 走看看