HOJ 12893 Just Enough Space

来源:互联网 发布:森海塞尔隔音效果 知乎 编辑:程序博客网 时间:2024/05/18 00:16

Just Enough SpaceTime Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KBTotal submit users: 7, Accepted users: 6Problem 12893 : No special judgementProblem description


Input


Output

one line with an integer: the number of GB you need to convert, or the string “FULL” if not enough diskspace can be freed.


Sample Input
32 500500 5004 2400400 600 700 10002 100010 10
Sample Output
5001300FULL
Problem SourceBAPC preliminary 2013


题目意思是你现在有n个磁盘,每个磁盘有一种功能,可以变成他容量的3倍。然后,你现在所有的磁盘都装满了容量,现在又来了一个数据data,需要放进你的磁盘,问,选择那些磁盘扩容能够容纳data,并且扩大的容量最小,输出你选择扩容的磁盘容量的和。这个题目的规模极其有意思,你的磁盘最多100个,每个最大2000G。而新来的数据data最大1e9G。对于题目分析,每个磁盘如果扩容,那么就是增加了2倍的容量,对于这个容量选还是不选,问题就成了0-1背包了,初看,对于容量那么大,1e9,0-1背包想想就爆了,可是仔细看看题意,100*2000*2=400000G < 1e9呀,那么容量就缩小到了400000在0-1背包范围内了。可是HOJ TLE了,大数据也会TLE了。同学有个很巧的想法,把1-400000做数组下标,初始化为0,把扩容极其所有组合对应的下标标记1,最后,对data-400000里离data最近的为1的i就是解了。

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<stack>#define rt return#define sf scanf#define pf printf#define si(n) sf("%d",&n)#define pi(n) pf("%d",n)#define REP0(i,n) for(int i=0;i<(n);i++)#define REP1(i,n) for(int i=1;i<=(n);i++)#define REP(i,s,n) for(int i=s;i<=(n);i++)#define db double#define pb push_back#define LL long long#define INF 0x3fffffff#define eps 1e-8#define PI acos(-1)#define maxn 400010using namespace std;int n,val;int dp[maxn],a[2010];int main(){    #ifdef ACBang//    freopen("in.txt","r",stdin);    #endif    int CAS;sf("%d",&CAS);    while(CAS--){        sf("%d%d",&n,&val);        int sum=0;        int MAX=-1;        REP0(i,n){            sf("%d",&a[i]);            a[i]*=2;            MAX=max(MAX,a[i]);            sum+=a[i];        }        if(sum<val){pf("FULL\n");continue;}        memset(dp,0,sizeof(dp));        for(int i=0;i<n;i++){            for(int v=val+MAX;v>=a[i];v--){                //想想为什么最大的容量只需从val+MAX就可以了??                dp[v]=max(dp[v],dp[v-a[i]]+a[i]);            }        }        for(int i=val;i<=val+MAX;i++){//dp肯定是非递减的            if(dp[i]>=val){                pf("%d\n",dp[i]/2);                break;            }        }    }    rt 0;}
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<stack>#define rt return#define sf scanf#define pf printf#define si(n) sf("%d",&n)#define pi(n) pf("%d",n)#define REP0(i,n) for(int i=0;i<(n);i++)#define REP1(i,n) for(int i=1;i<=(n);i++)#define REP(i,s,n) for(int i=s;i<=(n);i++)#define db double#define pb push_back#define LL long long#define INF 0x3fffffff#define eps 1e-8#define PI acos(-1)#define maxn 400010using namespace std;int n,val;int a[2010],b[maxn];int main(){    #ifdef ACBang//    freopen("in.txt","r",stdin);    #endif    int CAS;sf("%d",&CAS);    while(CAS--){        sf("%d%d",&n,&val);        int sum=0;        REP0(i,n){            sf("%d",&a[i]);            a[i]*=2;            sum+=a[i];        }        if(sum<val){pf("FULL\n");continue;}        memset(b,0,sizeof(b));        b[0]=1;        for(int i=0;i<n;i++){            for(int j=val;j>=0;j--){                if(b[j]==1)                    b[j+a[i]]=1;            }        }        int i;        for(i=val;i<maxn;i++){            if(b[i]==1){                pf("%d\n",i/2);                break;            }        }    }    rt 0;}


0 0