CF1458B Glass Half Spilled

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1458B Glass Half Spilled相关的知识,希望对你有一定的参考价值。

CF1458B Glass Half Spilled

题意:

有n杯水,第i杯有容积 a i a_{i} ai单位,初始时装有 b i b_{i} bi单位的水
现在你可以进行若干次操作,每次选择一杯水的一定水量并倒到另一杯水中,但是因为这些杯子形状非常奇怪,因此每倒一次水,倒的水会有一半洒在地上.
求出对于所有整数p满足 1 < = p < = n 1<=p<=n 1<=p<=n,求出进行若干次操作后选取p个杯子能获得水单位数量的最大值

题解:

每次倒水都会有损失,那么倒水的过程肯定不能出现同样的水来回倒,这样必不优。因此我们就直接选中p个杯子,让后将其他杯子里的水都倒进来。设选出的k个杯子的a值和为A且b值和为B,所有杯子的b值和为sumb。可以得到答案min{A,(sumb-B) * 0.5+B}=min{A,sumb * 0.5+B * 0.5}
现在我们就要求出对于每个A所对应的尽可能大的B(因为A是给出的,B不好求)
我们把A看作容积,把B看作价值,这不就是01背包,但本题A的容积不是固定的
A表示容积,而最多就100个杯子,每个杯子容积最大是100,也就是说A最大才10000,所以我们完全可以直接枚举容积
因为题目问k个杯子的情况,所以我们还需要一维来记录所选杯子数量
设dp[i][j]][k]:前i个杯子选了j个,且容积为k的最大价值(最大盛水容量)
我们可以通过滚动数组优化第一维
时间复杂度为 O ( n 4 ) O(n^4) O(n4)

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
    x= 0;
    char c= getchar();
    bool flag= 0;
    while (c < '0' || c > '9')
        flag|= (c == '-'), c= getchar();
    while (c >= '0' && c <= '9')
        x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
    if (flag)
        x= -x;
    read(Ar...);
}
template <typename T> inline void write(T x)
{
    if (x < 0) {
        x= ~(x - 1);
        putchar('-');
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#else
    startTime = clock ();
    freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
    endTime= clock();
    printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn=300;
struct node{
	int a,b;
}w[maxn];
int dp[102][10020];
int main()
{
    //rd_test();
	int n;
	read(n);
	int sum=0;
	for(int i=1;i<=n;i++){
		cin>>w[i].a>>w[i].b;
		sum+=w[i].b;
	}
	memset(dp,-INF_int,sizeof dp);
	dp[0][0]=0;
	for(int i=1;i<=n;i++){
		for(int j=i;j>=1;j--){
			for(int k=10000;k>=w[i].a;k--){
				dp[j][k]=max(dp[j][k],dp[j-1][k-w[i].a]+w[i].b);
			}
		}
	}
	for(int i=1;i<=n;i++){
		double ans=0;
		for(int k=0;k<=10000;k++){
			ans=max(ans,1.0*min(1.0*k,0.5*sum+0.5*dp[i][k]));
		}
		printf("%.9lf ",ans);
//		cout<<ans<<endl;
	}
	return 0;
    //Time_test();
}




以上是关于CF1458B Glass Half Spilled的主要内容,如果未能解决你的问题,请参考以下文章

CF 527C Glass Carving

杯子 (glass)

Glass:如何优雅地退出主菜单

Glass 应用程序在没有 Launchy 的情况下启动

Windows7 上的 Google Glass:无法访问设备

Glass Beads