zoukankan      html  css  js  c++  java
  • 【wqs二分 || 决策单调性】cf321E. Ciel and Gondolas

    把状态看成层,每层决策单调性处理

    题目描述

    题目大意

    众所周知,贞鱼是一种高智商水生动物。不过他们到了陆地上智商会减半。
    这不?他们遇到了大麻烦!
    n只贞鱼到陆地上乘车,现在有k辆汽车可以租用。
    由于贞鱼们并不能在陆地上自由行走,一辆车只能载一段连续的贞鱼。
    贞鱼们互相有着深深的怨念,每一对贞鱼之间有怨气值。
    第i只贞鱼与第j只贞鱼的怨气值记为Yij,且Yij=Yji,Yii=0。
    每辆车载重不限,但是每一对在同辆车中的贞鱼都会产生怨气值。
    当然,超级贞鱼zzp长者希望怨气值的总和最小。
    不过他智商已经减半,想不出分配方案。
    他现在找到了你,请你帮助他分配贞鱼们,并输出最小怨气值之和ans。
    n<=4000,1 ≤ k ≤min(n , 800)


    题目分析

    做法一:wqs二分

    这个题第一眼就像是wqs二分,并且答案函数的确是一个凸函数的形状。

    于是首先是个wqs二分的模板题。

     1 #include<bits/stdc++.h>
     2 typedef long long ll;
     3 const int maxn = 4035;
     4 const int INF = 0x3f3f3f3f;
     5 
     6 int n,k,L,R;
     7 ll a[maxn][maxn],g[maxn][maxn],f[maxn],h[maxn],ans;
     8 
     9 char tc(){static char tr[1000000],*A=tr,*B=tr;return A==B&&(B=(A=tr)+fread(tr,1,1000000,stdin),A==B)?EOF:*A++;}
    10 #define getchar tc
    11 int read()
    12 {
    13     char ch = getchar();
    14     int num = 0, fl = 1;
    15     for (; !isdigit(ch); ch=getchar())
    16         if (ch=='-') fl = -1;
    17     for (; isdigit(ch); ch=getchar())
    18         num = (num<<1)+(num<<3)+ch-48;
    19     return num*fl;
    20 }
    21 ll check(int w)
    22 {
    23     memset(f, 0x3f3f3f3f, sizeof f);
    24     memset(h, 0x3f3f3f3f, sizeof h);
    25     f[0] = h[0] = 0;
    26     for (int i=1; i<=n; i++)
    27         for (int j=0; j<i; j++)
    28             if (f[i] > f[j]+g[j+1][i]+w||(f[i]==f[j]+g[j+1][i]+w&&h[j]+1 < h[i])){
    29                 f[i] = f[j]+g[j+1][i]+w, h[i] = h[j]+1;
    30             }
    31     if (h[n] <= k) ans = f[n]-k*w;
    32     return h[n];
    33 }
    34 int main()
    35 {
    36     n = read(), k = read();
    37     for (int i=1; i<=n; i++)
    38         for (int j=1; j<=n; j++) a[i][j] = read();
    39     for (int i=n; i>=1; i--)
    40         for (int j=i; j<=n; j++)
    41             g[i][j] = g[i+1][j]+g[i][j-1]-g[i+1][j-1]+a[i][j];
    42     ans = INF, L = 0, R = g[1][n];
    43     for (int mid=(L+R)>>1; L<=R; mid=(L+R)>>1)
    44         if (check(mid) <= k) R = mid-1;
    45         else L = mid+1;
    46     printf("%lld
    ",ans);
    47     return 0;
    48 }

    做法二:决策单调性

    $n^2$dp是$f[j][i]$表示前$i$个鱼分为$j$组的最小代价。对于每一个同样的$j$,其转移是具有单调性的。那就是说把$i$视作层,剩下的就是层之间的转移。

    暂时还没写。

    END

  • 相关阅读:
    ajax
    vue 思維導圖
    python项目_log日志的使用
    mysql数据库_serialisers
    常见的时间复杂度及其增长速度比较
    C++中的sort()函数
    用C++实现输入三个整数,中间用逗号隔开
    python——递归函数
    python——函数
    python——可变对象和不可变对象
  • 原文地址:https://www.cnblogs.com/antiquality/p/11311625.html
Copyright © 2011-2022 走看看