题意:给定k种类型的砖头,每种砖头有3个属性,分别是高度,最大高度,数量。其中最大高度表示用这种砖头建的台阶最大高度不超过它。求利用这些砖头可以搭成最大高度的台阶。
分析:有数量,有最大值,明显的多重背包。但是每种类型都有最大高度限制。这怎么办?
思路:这里的最大高度限制类比到背包里不就是容量限制吗? 所以将最大高度限制设置成背包容量就行了。不过这里还需要一定转化,那就是选砖头的时候,一定是先考虑选最大高度小的放在最低层,这些才能保证有最优解,这其实是一个很明显的贪心问题。
所以,这是一道先贪心,后多重背包的题目。
反思:这题也做了好久,一开始卡在了不知道如何处理最大高度的问题上,想通了以后又卡在了java语法上,最后没办法只能上c++了。
C++代码:(多重背包的时候,我还是做了2进制优化)
#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <string>
#include <string.h>
#include <math.h>
#include <sstream>
using namespace std;
const int maxn=1e5+9;
int dp[maxn];
int v[maxn],h[maxn];
struct Point{
int h,a,c;
}p[maxn];
bool cmp(Point a,Point b){
return a.a<b.a;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int k;
cin>>k;
int M=0;
for(int i=0;i<k;i++)
{
scanf("%d%d%d",&p[i].h,&p[i].a,&p[i].c);
M=max(M,p[i].a);
}
sort(p,p+k,cmp);
memset(dp,0,sizeof(dp));
int cnt=0;
for(int i=0;i<k;i++)
{
for(int j=1;j<=p[i].c;j*=2)
{
cnt=j*p[i].h;
for(int t=p[i].a;t>=cnt;t--){
dp[t]=max(dp[t],dp[t-cnt]+cnt);
}
p[i].c-=j;
}
if(p[i].c>0){
cnt=p[i].c*p[i].h;
for(int t=p[i].a;t>=cnt;t--){
dp[t]=max(dp[t],dp[t-cnt]+cnt);
}
}
}
int ans=0;
for(int i=M;i>=0;i--)
{
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
return 0;
}
java语法有问题的代码:(求大佬帮忙debug)
package com.example.demo.ACM;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
/**
* @ClassName POJ2392
* @Description TODO
* @Auther ydc
* @Date 2019/1/28 8:29
* @Version 1.0
**/
public class POJ2392 {
final static int maxn=1000005;
public static int [] dp = new int [maxn];
public static void main(String [] args) {
int k;
Scanner cin = new Scanner(System.in);
k = cin.nextInt();
Point [] p = new Point[k+100];
int M=0;
for(int i=0;i<k;i++){
int x,y,z;
x=cin.nextInt();
y=cin.nextInt();
z=cin.nextInt();
p[i] =new Point();
p[i].h=x;
p[i].a=y;
p[i].c=z;
M=Math.max(M,p[i].a);
}
Arrays.sort(p,new cmp());
int cnt;
for(int i=0;i<k;i++){
for(int j=1;j<=p[i].c;j*=2){
cnt=j*p[i].h;
for(int t=p[i].a;t>=cnt;t--){
dp[t]=Math.max(dp[t],dp[t-cnt]+cnt);
}
p[i].c-=j;
}
if(p[i].c>0){
cnt=p[i].c*p[i].h;
for(int t=p[i].a;t>=cnt;t--){
dp[t]=Math.max(dp[t],dp[t-cnt]+cnt);
}
}
}
int ans=0;
for(int i=M;i>=0;i--){
ans=Math.max(ans,dp[i]);
}
System.out.println(ans);
cin.close();
}
}
class cmp implements Comparator<Point>{
public int compare(Point a,Point b){
return a.a-b.a;
}
}
class Point{
int h,a,c;
}