Just Enough Space |
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB |
Total submit users: 7, Accepted users: 6 |
Problem 12893 : No special judgement |
Problem 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 |
3 2 500 500 500 4 2400 400 600 700 1000 2 1000 10 10 |
Sample Output |
500 1300 FULL |
Problem Source |
BAPC 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 400010
using 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 400010
using 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;
}