• 【五校联考6day2】er


    这题首先是:

    分类讨论

    首先,我们可以知道,最优解一定是先“1”再“2”后“3”!(为什么自己想)
    然后,我们可以发现,要是选的话,一定是从大选到小(为什么自己想)
    嗯嗯,n=1的情况是很简单的,然后我们考虑n=2的//o(*  ̄︶ ̄ * )o//
    n=2的我们可以DP!!!
    有两种做法:
    第一种:(简单又自然,就是有点慢)
    在这里插入图片描述
    我们设f[j]表示当前(就是前i个)这个东西是否能够构成。
    这样子就是转移的话很费时间。(┭┮﹏┭┮)

    但能过(O(∩_∩)O哈哈~)

    上标:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define db double
    using namespace std;
    int n,M,K,a[11],e=0,p[310],m0=0,p0=0;
    int f[200010];
    db s,ans=0,m[310];
    
    inline int read()
    {
    	int x=0,f=0; char c=getchar();
    	while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return f ? -x:x;
    }
    
    inline int cmp(int x,int y) {return x>y;} 
    
    inline int cmp1(db x,db y) {return x>y;}
    
    int main()
    {
    	n=read(),M=read(),K=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1,x,y;i<=M;i++)
    	{
    		x=read(),y=read();
    		if (x==1) {e=y; continue;}
    		if (!y) continue;
    		if (x==2) p[++p0]=y;
    		else m[++m0]=log(y);
    	}
    	sort(p+1,p+p0+1,cmp);
    	sort(m+1,m+m0+1,cmp1);
    	for (int i=2;i<=p0;i++) p[i]+=p[i-1];
    	for (int i=2;i<=m0;i++) m[i]+=m[i-1];
    	if (n==1)
    	{
    		for (int i=0;i<=min(K,p0);i++)
    		{
    			ans=std::max(ans,log(p[i]+a[1])+m[std::min(K-i,m0)]);
    			if (i<K) ans=std::max(ans,log(p[i]+e)+m[std::min(K-i-1,m0)]);
    		}
    		printf("%.3lf
    ",ans);
    	}
    	else
    	{
    		f[0]=1;
    		for (int i=0;i<=min(K,p0);i++)	
    		{
    			for (int j=p[p0];j>=p[i]-p[i-1];j--)
    				f[j]=max(f[j],f[j-p[i]+p[i-1]]);
    			for (int j=0;j<=p[i];j++)
    				if (f[j] && f[p[i]-j])
    				{
    					ans=std::max(ans,log(j+a[1])+log(p[i]-j+a[2])+m[std::min(K-i,m0)]);
    					ans=std::max(ans,log(j+a[2])+log(p[i]-j+a[1])+m[std::min(K-i,m0)]);
    					ans=std::max(ans,log(j+e)+log(p[i]-j+std::max(a[1],a[2]))+m[std::min(K-i-1,m0)]);
    					ans=std::max(ans,log(j+std::max(a[1],a[2]))+log(p[i]-j+e)+m[std::min(K-i-1,m0)]);
    				}
    		}
    		printf("%.3lf
    ",ans);
    	}
    	return 0;
    }
    

    第二种:(有人说很容易想到。。。)
    我们设f[i][j]表示前i个加法东东
    然后我们可以将其转移到:
    f[i+1][j+p[i]]=max(~,f[i][j]);
    f[i+1][j]=max(~,f[i][j]+p[i]);
    然后赋值东东就自己特判一下就好了。
    上标:(为了跑快点不惜一切代价(但就是不吸!o( ̄ヘ ̄o#)))

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define db double
    using namespace std;
    int n,M,K,a[11],e=0,p[310],m0=0,p0=0;
    int f[110][202010],now;
    db s,ans=0,m[310],sum[110];
    
    inline int read()
    {
    	int x=0,f=0; char c=getchar();
    	while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return f ? -x:x;
    }
    
    inline int cmp(int x,int y) {return x>y;} 
    
    inline int cmp1(db x,db y) {return x>y;}
    
    int main()
    {
    	freopen("er.in","r",stdin);
    	freopen("er.out","w",stdout);
    	n=read(),M=read(),K=read();
    	a[1]=read();
    	if (n>1)
    	{
    		a[2]=read();
    		if (a[1]>a[2]) swap(a[1],a[2]);
    	}
    	for (int i=1,x,y;i<=M;i++)
    	{
    		x=read(),y=read();
    		if (x==1) {e=y; continue;}
    		if (!y) continue;
    		if (x==2) p[++p0]=y;
    		else m[++m0]=std::log(y);
    	}
    	sort(p+1,p+p0+1,cmp);
    	sort(m+1,m+m0+1,cmp1);
    	for (int i=2;i<=m0;i++) m[i]+=m[i-1];
    	if (n==1)
    	{
    		for (int i=0;i<=min(K,p0);i++)
    		{
    			ans=std::max(ans,log(p[i]+a[1])+m[std::min(K-i,m0)]);
    			if (i<K) ans=std::max(ans,log(p[i]+e)+m[std::min(K-i-1,m0)]);
    		}
    		printf("%.3lf
    ",ans);
    	}
    	else
    	{
    		f[0][a[1]]=a[2];now=e+p[1];
    		f[1][a[1]+p[1]]=std::max(f[1][a[1]+p[1]],f[0][a[1]]);
    		f[1][a[1]]=std::max(f[1][a[1]],f[0][a[1]]+p[1]);
    		sum[0]=std::max(sum[0],1.0*f[0][a[1]]*a[1]);
    		for (int i=1;i<p0;i++)
    		{
    			now+=p[i+1];
    			for (int j=0;j<=now;j++)
    				if (f[i][j])
    				{
    					f[i+1][j+p[i+1]]=std::max(f[i+1][j+p[i+1]],f[i][j]);
    					f[i+1][j]=std::max(f[i+1][j],f[i][j]+p[i+1]);
    					sum[i]=std::max(sum[i],1.0*f[i][j]*j);
    					sum[i]=std::max(sum[i],f[i-1][j]*(j-a[1]+e)*1.0);
    				}
    		}
    		for (int i=0;i<=now;i++)
    			sum[p0]=std::max(sum[p0],f[p0][i]*i*1.0);
    		for (int i=0;i<=K;i++)
    			if (sum[i]) sum[i]=std::log(sum[i]);
    		ans=max(ans,sum[K]);
    		for (int i=1;i<=std::min(m0,K);i++)
    			if (sum[K-i]) ans=std::max(ans,sum[K-i]+m[i]);
    		printf("%.3lf
    ",ans);
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    react 有多个按钮时点击单个按钮独立控制Loading
    React路由通信
    体育竞技模拟比赛
    json与csv格式相互转换
    替换表格内容及csv转html及CGI
    excel转换成csv格式
    文件读写笔记
    自定义手绘风
    numpy&matplotlib读书笔记
    Python成绩雷达图
  • 原文地址:https://www.cnblogs.com/jz929/p/11817605.html
Copyright © 2020-2023  润新知