首页 > 代码库 > 【四校联考】立方体

【四校联考】立方体

【题目描述】

你有一个背包,你要往里面塞一些立方体。每次,在保证背包里所有立方体的体积和不超过背包容量的前提下,你会选择一个边长为整数且尽可能大的立方体塞进背包里。

背包的容量为[1,n]中的整数,你想知道你最多能拿到多少个立方体,以及在此前提下,背包容量的最小值和最大值。

【输入数据】

一行一个整数n。

【输出数据】

      三行,每行一个整数,分别表示最多立方体个数,容量最小值和容量最大值。

【样例输入】

14

【样例输出】

7

7

14

【数据范围】

对于20%的数据,n<=1000。

对于40%的数据,n<=100000。

对于100%的数据,1<=n<=10^15

 

【题解】

ysy题解搬运

 考虑最终取到的立方体,从小到大排序后要满足x1^3+x2^3+…+xi^3<(xi+1)^3。

 考虑前两问,从x1开始逐步确定每个数,显然xi越小,后面的限制也越宽松,所以贪心取最小的即可。

 考虑第三问。首先我们发现,由于取立方体时是从大到小取的,因此对于两种方案,如果x[i+1]=y[i+1],x[i+2]=y[i+2],..,x[m]=y[m],并且xi>yi,那么x一定比y大

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#define il inline
using namespace std;
typedef long long ll;
ll n,p,q,t,tot,x[1000001];
ll s(ll a){
    return a*a*a;
}
il void init(){
    cin>>n;
    for(ll i=1;p+s(i)<=n;i++)
        while(p+s(i)<s(i+1)){
            x[++tot]=i;
            p+=s(i);
        }
    cout<<tot<<endl<<p<<endl;
    q=p;t=n-p;
    for(int i=tot;i>0;i--){
        p-=s(x[i]);
        q-=s(x[i]);
        while(s(x[i]+1)-s(x[i])<=t){
            t-=s(x[i]+1)-s(x[i]);
            x[i]++;
        }
        p+=s(x[i]);
        t=min(t,s(x[i]+1)-s(x[i])-q-1);
    }
    cout<<p<<endl;
}
int main(){
    freopen("cube.in","r",stdin);
    freopen("cube.out","w",stdout);
    init();
    return 0;
}

 

【四校联考】立方体