2018.12.15【NOIP提高组】模拟B组 JZOJ 100044 abcd

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/85014698

题目

JZOJ 100004 abcd


思路

其实就是一个多重背包
二进制拆分跑得比单调队列优化还快。。。


代码(二进制优化)

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;int n,m,tmp,num;
int a,b[211],c[211],d[211];
int w[10009],p[10009],f[100009];
inline char Getchar()
{
    static char buf[100000],*p1=buf+100000,*pend=buf+100000;
    if(p1==pend)
	{
        p1=buf; pend=buf+fread(buf,1,100000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline long long read()
{
	char c;int d=1;long long f=0;
	while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void write(register long long x)
{
	if(x<0)write(45),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
	return;
}
inline void cal(register int gs,register int wx,register int px)
{
    for(int i=1;i<=gs;i<<=1)
	{
        w[++num]=wx*i;p[num]=px*i;
        gs-=i;
    }
    if(gs){w[++num]=gs*wx;p[num]=px*gs;}
    return;
}
signed main()
{
	freopen("1.txt","r",stdin);
	memset(f,0xcf,sizeof(f));f[0]=0;
	n=read();
	for(register int i=1;i<=n;i++)
	{
		a=read();b[i]=read();c[i]=read();d[i]=read();
		b[i]-=a;tmp+=a*d[i];m-=a*c[i];
	}
	for(int i=1;i<=n;i++)cal(b[i],c[i],d[i]);
	for(register int i=1;i<=num;i++) for(register int j=m;j>=w[i];j--)
	f[j]=max(f[j],f[j-w[i]]+p[i]);
	write(f[m]+tmp);
}

代码(单调队列)

#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;int n,m,tmp,num,t,i,j,k;
int a,w[211],c[211],v[211],f[2][100009],l,r;
inline char Getchar()
{
    static char buf[100000],*p1=buf+100000,*pend=buf+100000;
    if(p1==pend)
	{
        p1=buf; pend=buf+fread(buf,1,100000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline long long read()
{
	char c;int d=1;long long f=0;
	while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void write(register long long x)
{
	if(x<0)putchar(45),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
	return;
}
int q[211],sd;
inline int calc(register int k){return f[!t][j+k*w[i]]-k*v[i];}
signed main()
{
	freopen("1.txt","r",stdin);
	n=read();
	for(register int i=1;i<=n;i++)
	{
		a=read();c[i]=read();w[i]=read();v[i]=read();
		c[i]-=a;tmp+=a*v[i];m-=a*w[i];
	}
	for(register int i=1;i<=m;i++) f[0][i]=-1e9;
	for(i=1;i<=n;i++)
	{
		t=!t;sd+=c[i]*w[i];if(sd>m)sd=m;
		for(j=0;j<w[i];j++)
		{
			l=1;r=0;
			int maxp=(sd-j)/w[i];
			for(k=0;k<=maxp;k++)
			{
				while(l<=r&&calc(q[r])<calc(k))r--;q[++r]=k;
				if(q[l]+c[i]<k)l++;
				f[t][k*w[i]+j]=f[!t][q[l]*w[i]+j]+(k-q[l])*v[i];
			}
		}
	}
	write(f[t][m]+tmp);
}

代码(STL)

#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;int n,m,tmp,num,t,i,j,k;
int a,w[211],c[211],v[211],f[2][100009],l,r;
inline char Getchar()
{
    static char buf[100000],*p1=buf+100000,*pend=buf+100000;
    if(p1==pend)
	{
        p1=buf; pend=buf+fread(buf,1,100000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline long long read()
{
	char c;int d=1;long long f=0;
	while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void write(register long long x)
{
	if(x<0)putchar(45),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
	return;
}
deque<int>q;
int sd;
inline int calc(register int k){return f[!t][j+k*w[i]]-k*v[i];}
signed main()
{
	n=read();
	for(register int i=1;i<=n;i++)
	{
		a=read();c[i]=read();w[i]=read();v[i]=read();
		c[i]-=a;tmp+=a*v[i];m-=a*w[i];
	}
	for(register int i=1;i<=m;i++) f[0][i]=-1e9;
	for(i=1;i<=n;i++)
	{
		t=!t;sd+=c[i]*w[i];if(sd>m)sd=m;
		for(j=0;j<w[i];j++)
		{
			while(q.size())q.pop_front();
			l=1;r=0;
			int maxp=(sd-j)/w[i];
			for(k=0;k<=maxp;k++)
			{
				while(q.size()&&calc(q.back())<calc(k)) q.pop_back();q.push_back(k);
				if(q.front()+c[i]<k) q.pop_front();
				f[t][k*w[i]+j]=f[!t][q.front()*w[i]+j]+(k-q.front())*v[i];
			}
		}
	}
	write(f[t][m]+tmp);
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/85014698