http://acm.hdu.edu.cn/showproblem.php?pid=1069
又读错题了...砖块每类有无数个...不是只能用一次
题意:
有m种砖,每种砖有长宽高3种属性,把砖摞成一摞,问最高能多高.
砖i能放在砖j上 当且仅当 i长<j长&&i宽<j宽.
思路:
一开始想直接dp,但是发现没有给value的大小,索性离散化一下.
dp[i][j]表示当前摞的顶端宽为v[i],长为v[j],dp[i][j]为当前最优高度
用每个状态的砖块更新dp[i][j]即可
离散化:
VALUE: 离散化前的值
value: 离散化后的值
知道value找VALUE: v[value] → VALUE
知道VALUE找value: lower_bound(v,VALUE)-v.begin() → value
代码:
#include<bits/stdc++.h>
#define fuck(x) std::cout<<"["<<#x<<"->"<<x<<"]"<<endl;
using namespace std;
typedef long long ll;
const int M=2e5+5;
const int inf=1e9+5;
int n,dp[100][100];
int x[35],y[35],z[35];
int main() {
int caz=1;
while(~scanf("%d",&n)&&n) {
vector<int>v;
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++) {
scanf("%d%d%d",&x[i],&y[i],&z[i]);
v.push_back(x[i]);
v.push_back(y[i]);
v.push_back(z[i]);
}
sort(v.begin(),v.end());
int m=unique(v.begin(),v.end())-v.begin();
v.erase(v.begin()+m,v.end());
// erase后, m就是v.size()
for(int i=1; i<=n; i++) {
int posx=lower_bound(v.begin(),v.end(),x[i])-v.begin();
int posy=lower_bound(v.begin(),v.end(),y[i])-v.begin();
int posz=lower_bound(v.begin(),v.end(),z[i])-v.begin();
dp[posx][posy]=max(dp[posx][posy],z[i]);
dp[posy][posx]=max(dp[posy][posx],z[i]);
dp[posz][posy]=max(dp[posz][posy],x[i]);
dp[posy][posz]=max(dp[posy][posz],x[i]);
dp[posx][posz]=max(dp[posx][posz],y[i]);
dp[posz][posx]=max(dp[posz][posx],y[i]);
}
for(int i=m-1; i>=0; i--) {
for(int j=m-1; j>=0; j--) {
for(int k=1; k<=n; k++) {
int posx=lower_bound(v.begin(),v.end(),x[k])-v.begin();
int posy=lower_bound(v.begin(),v.end(),y[k])-v.begin();
int posz=lower_bound(v.begin(),v.end(),z[k])-v.begin();
if(i>posx&&j>posy)
dp[posx][posy]=max(dp[posx][posy],dp[i][j]+z[k]);
if(i>posy&&j>posx)
dp[posy][posx]=max(dp[posy][posx],dp[i][j]+z[k]);
if(i>posz&&j>posy)
dp[posz][posy]=max(dp[posz][posy],dp[i][j]+x[k]);
if(i>posy&&j>posz)
dp[posy][posz]=max(dp[posy][posz],dp[i][j]+x[k]);
if(i>posx&&j>posz)
dp[posx][posz]=max(dp[posx][posz],dp[i][j]+y[k]);
if(i>posz&&j>posx)
dp[posz][posx]=max(dp[posz][posx],dp[i][j]+y[k]);
}
}
}
int ans=0;
for(int i=0; i<m; i++) {
for(int j=0; j<m; j++) {
ans=max(ans,dp[i][j]);
}
}
printf("Case %d: maximum height = %d\n",caz++,ans);
}
return 0;
}