2019牛客暑期多校训练营(第十场)J Wood Processing 斜率DP or 分治DP

题意:

2019牛客暑期多校训练营(第十场)J Wood Processing 斜率DP or 分治DP_第1张图片

n块矩形,问你合并成K块,切掉的面积最小是多少

思路1:斜率DP

首先按照高度从小到大排序

F[I][J]表示前i块矩形,划分成J块的最小代价。则

F[I][J]=min(F[I][J],F[K][J-1]+W(K+1,I))

W(i,j)表示把i到j这些合并一起的代价,sum[i]-sum[k]- h[k+1]*(sumw[i]-sumw[k]).

最后整理可得如下形式的斜率式:F[I]+A[I]*A[J]=F[J]+C[J](b+kx=y)

#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=b;i>=a;i--)
using namespace std;
#define ll long long
ll rd()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
 
struct node{
    ll w,h;
}p[50100],qq[50100];
ll sumw[50100],sum[50100];
const int N=50100;
int now,pre;
ll s[N],f[N][2],n,x,L,j,q[N],tail,head,k;
inline double X(ll i) {return p[i+1].h;}
inline double Y(ll i) {return f[i][pre]-sum[i]+p[i+1].h*sumw[i];}
inline double slope(ll i,ll j){return (Y(j)-Y(i))/(X(j)-X(i));}
 
bool cmp(node a,node b)
{
    return a.hslope(q[tail],i)) tail--;
            q[++tail]=i;   
        }
//      rep(i,1,n) printf("%d ",f[i][now]);
//      printf("\n");
    }
    printf("%lld\n",f[n][now]);
}

思路2:分治DP

打表可得,F[I]是从J转移过来的,F[i-1]是从K转移过来的,J始终>=K,则可用分治DP。

 

思路3:wqs带权二分(待补)

你可能感兴趣的:(DP,牛客)