zoukankan      html  css  js  c++  java
  • BZOJ 1933 Bookcase 书柜的尺寸

    Description

    Tom不喜欢那种一字长龙式的大书架,他只想要一个小书柜来存放他的系列工具书。Tom打算把书柜放在桌子的后面,这样需要查书的时候就可以不用起身离开了。显然,这种书柜不能太大,Tom希望它的体积越小越好。另外,出于他的审美要求,他只想要一个三层的书柜。为了物尽其用,Tom规定每层必须至少放一本书。现在的问题是,Tom怎么分配他的工具书,才能让木匠造出最小的书柜来呢? Tom很快意识到这是一个数学问题。每本书都有自己的高度hi和厚度ti。我们需要求的是一个分配方案,也就是要求把所有的书分配在S1、S2和S3三个非空集合里面的一个,不重复也不遗漏,那么,很明显,书柜正面表面积(S)的计算公式就是: 由于书柜的深度是固定的(显然,它应该等于那本最宽的书的长度),所以要求书柜的体积最小就是要求S最小。Tom离答案只有一步之遥了。不过很遗憾,Tom并不擅长于编程,于是他邀请你来帮助他解决这个问题。

    Input

    文件的第一行只有一个整数n(3≤n≤70),代表书本的本数。接下来有n行,每行有两个整数hi和ti,代表每本书的高度和厚度,我们保证150≤hi≤300,5≤ti≤30。

    Output

    只有一行,即输出最小的S。

    Sample Input

    4
    220 29
    195 20
    200 9
    180 30

    Sample Output

    18000

    HINT

    Source

    Day2

    F[I][J][K]表示操作到第i本书,第一层的书的厚度为J,第二层书的厚度为K,则第三层的厚度为SUM[I]-I-J,记录的是最小的高度。(按照高度从小到大排序,这样就没有后效性了) 时间复杂度O(70*2100*2100),空间复杂度O(2*2100*2100) 开滚动数组

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #define ll long long
    #define maxn 4001000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define PI 2*asin(1)
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define SWAP(x,y,t) ( (t)=(x),(x)=(y),(y)=(t) )
    using namespace std;
    struct node{
    	int h,t;
    }a[1010];
    int f[2][2110][2110];
    int n,sum[1010],ans=10101010;
    bool cmp(node a,node b)
    {
    	return a.h>b.h;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d%d",&a[i].h,&a[i].t);
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i].t;
    	memset(f,127/3,sizeof(f));
    	f[0][0][0]=0;
    	int sta=0;
    	for(int i=1;i<=n;i++)
    	{
    		sta=!sta;
    		memset(f[sta],127/3,sizeof(f[sta]));
    		for(int j=sum[i-1];j>=0;j--)
    			for(int k=sum[i-1];k>=0;k--)
    			{
    				if(j+k>sum[i-1]||f[!sta][j][k]>101010) continue;
    				int t=a[i].t,h=a[i].h;
    				
    				if(j==0) f[sta][t][k]=min(f[sta][t][k],f[!sta][j][k]+h);
    				else f[sta][j+t][k]=min(f[sta][j+t][k],f[!sta][j][k]);
    				
    				if(k==0) f[sta][j][t]=min(f[sta][j][t],f[!sta][j][k]+h);
    				else f[sta][j][k+t]=min(f[sta][j][k+t],f[!sta][j][k]);
    				
    				if(sum[i-1]-k-j==0) f[sta][j][k]=min(f[sta][j][k],f[!sta][j][k]+h);
    				else f[sta][j][k]=min(f[sta][j][k],f[!sta][j][k]);
    			}
    	}
    	for(int i=1;i<sum[n];i++)
    		for(int j=1;j<sum[n];j++)
    	 		if(i+j<sum[n] && f[sta][i][j]<101010)
    	 		    {
    	    		ans=min(ans,max(max(i,j),sum[n]-i-j)*f[sta][i][j]);
    	    		//printf("i=%d j=%d sum[n]=%d %d %d f[sta][i][j]=%d
    ",i,j,sum[n],max(max(i,j),sum[n]-i-j)*f[sta][i][j],max(max(i,j),sum[n]-i-j),f[sta][i][j]);
    	    	    }
    	printf("%d
    ",ans);
    
    } 
    
  • 相关阅读:
    Linux常用命令
    全文搜索服务器solr
    非关系型数据库之redis
    springMVC流程
    浅谈spring框架的控制反转和依赖注入
    Java基础之数组
    Java基础之方法
    跨域访问接口,传递参数
    Centos 6无法使用yum
    内网穿透工具:钉钉HTTP内网穿透使用与讲解
  • 原文地址:https://www.cnblogs.com/The-Pines-of-Star/p/9878812.html
Copyright © 2011-2022 走看看