标签:开始 include div 更新 std 避免 set 宽度 sizeof
神奇的dp优化。
考虑6维状态的dp,分别表示三行高和宽,显然MLE&&TLE。
把高排个序,从大到小往架上放,那么若不是重开一行便对高度没有影响。
然后求出宽度的sum,dp[i][j]表示第一行放了i的宽度,二行放了j的宽度,三行放了sum-i-j宽度的最小的高度值。
先把所有书放在第三行,然后从第二本开始转移,考虑往其他行移的情况。
避免MLE要滚动数组。
注意最后更新答案时保证i>0&&j>0&&sum-i-j>0且dp[i][j]!=INF;
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<ctime>
typedef long long LL;
using namespace std;
int n,sum,f[2][2150][2150],ans=1e9;
struct book {
int hi,ti;
friend bool operator <(const book &A,const book &B) {
return A.hi>B.hi;
}
}bk[75];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&bk[i].hi,&bk[i].ti);
sort(bk+1,bk+n+1);
for(int i=1;i<=n;i++) sum+=bk[i].ti;
int o=0;
memset(f,127/3,sizeof(f));
f[0][0][0]=bk[1].hi;
for(int i=2;i<=n;i++) {
o^=1;
for(int j=0;j<=sum;j++) {
for(int k=0;k<=sum&&j+k<sum;k++) {
f[o][j][k]=min(f[o][j][k],f[o^1][j][k]);
if(!j) f[o][j+bk[i].ti][k]=min(f[o][j+bk[i].ti][k],f[o^1][j][k]+bk[i].hi);
else f[o][j+bk[i].ti][k]=min(f[o][j+bk[i].ti][k],f[o^1][j][k]);
if(!k) f[o][j][k+bk[i].ti]=min(f[o][j][k+bk[i].ti],f[o^1][j][k]+bk[i].hi);
else f[o][j][k+bk[i].ti]=min(f[o][j][k+bk[i].ti],f[o^1][j][k]);
if(i==n&&j!=0&&k!=0&&f[o][j][k]!=707406378) {
ans=min(ans,f[o][j][k]*max(max(j,k),sum-j-k));
}
}
}
}
printf("%d\n",ans);
return 0;
}
BZOJ 1933 [Shoi2007]Bookcase 书柜的尺寸
标签:开始 include div 更新 std 避免 set 宽度 sizeof
原文地址:http://www.cnblogs.com/Achenchen/p/7612025.html