您的位置:首页 > 其它

HDU 3669 Cross the Wall (斜率优化DP)

2015-07-30 11:30 441 查看
先将各矩形按照w从小到大排序。

设dp[i]为考虑前i个矩形的总的最小面积。

dp[i] = min(dp[i], dp[j] + h[k]*w[i]) k为从j+1到i的高度最大的矩形。

那么这样复杂度n^3必然T。

考虑这样一个事实:将矩形排序后,考虑第i个矩形,前i-1个矩形中高度比它小的必然可以被包含于第i个矩形,我们只需要考虑排序后矩形中高度降序的矩形。

那么方程就变为dp[i] = min(dp[i], dp[j] + h[j+1]*w[i])。

然后斜率优化就完了。

我的代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>

using namespace std;
typedef long long LL;
const LL maxn = 50005;

struct Nod{
LL w,h;
bool operator < (const Nod &z) const{
return w < z.w;
}
};

LL n,k,dp[105][maxn],w[maxn],h[maxn];
LL q[maxn],hd,tl;
vector<Nod> vec;

void init(){
vec.clear();
memset(dp,63,sizeof(dp));
dp[0][0] = 0;
}

LL getDP(LL j,LL k,LL i){
return dp[i-1][k] + w[j]*h[k+1];
}
LL getUp(LL j,LL k,LL i){
return dp[i-1][k] - dp[i-1][j];
}
LL getDown(LL j,LL k){
return h[j+1] - h[k+1];
}

void solve(){
for(LL i=1;i<=k;i++){
hd = tl = 0;
q[tl++] = i-1;
for(LL j=i;j<=n;j++){
while(hd+1<tl && getUp(q[hd],q[hd+1],i)
<= w[j]*getDown(q[hd],q[hd+1])) hd++;
dp[i][j] = getDP(j,q[hd],i);
//printf("%lld %lld %lld %lld\n",j,q[hd],i,dp[i][j]);
while(hd+1<tl && getUp(q[tl-1],j,i)*getDown(q[tl-2],q[tl-1])
<= getUp(q[tl-2],q[tl-1],i)*getDown(q[tl-1],j)) tl--;
q[tl++] = j;
}
}
LL ans = 1e12;
for(int i=1;i<=k;i++) ans = min(ans,dp[i]
);
printf("%lld\n",ans);
}

int main(){
while(~scanf("%lld%lld",&n,&k)){
init();
Nod o;
for(LL i=0;i<n;i++){
scanf("%lld%lld",&o.w,&o.h);
vec.push_back(o);
}
sort(vec.begin(),vec.end());
n = 0;
for(LL i=0;i<vec.size();i++){
while(n >= 1 && vec[i].h >= h
) n--;
n++;
w
= vec[i].w;h
= vec[i].h;
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: