zoukankan      html  css  js  c++  java
  • 8.9 正睿暑期集训营 Day6


    2018.8.9 正睿暑期集训营 Day6

    时间:2.5h(实际)
    期望得分:60+30+0
    实际得分:40+30+0

    比赛链接
    这里也有一些

    为什么A就是40分。。这个咋就能150+ms过呢。。http://www.zhengruioi.com/submission/26647

    A 萌新拆塔(状压DP)

    题目链接

    如果杀掉的怪物和吃的宝石已知,那么状态也是可以直接算出来的(预处理),只需要求该状态的最大血量。
    n很小,于是只需要2^n枚举已击杀的怪的状态,枚举下个怪转移DP最大血量?
    因为有模仿怪,所以杀掉怪物后立即吃宝石不一定是最优的。
    宝石只有在杀掉怪物后才能吃,即每个怪物有三种状态,3^n枚举就可以了。
    已知状态可以算出清了哪些怪、还有哪些宝石没吃,但是可以直接用s1[s],s2[s]记录s状态清了哪些怪、吃了哪些宝石,可以直接在转移时更新(或是预处理,不过这么多次取模、除法会更慢?),枚举时也可以直接枚举里面的0(异或后lowbit枚举1)。
    如果要吃某个宝石i,那么怪物i已经杀掉了,即状态s中i这一位已经是1(已经加过pw[i]),此时吃掉宝石变成2,直接再加pw[i]即可。
    复杂度O(3^n*n)。

    //3346ms	77996kb
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define lb(x) (x&-x)
    #define gc() getchar()
    typedef long long LL;
    const int N=(1<<14)+5,M=5e6;
    
    int pw[16],bit[N],ok[16],sap[N],sdp[N],smp[N],s1[M],s2[M];
    LL f[M];
    struct Monster
    {
    	int H,A,D,S,ap,dp,mp,hp;
    }A[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    LL Combat(Monster mon,LL hp,int atk,int def,int mdf)
    {
    	if(mon.S&8) mon.A=atk, mon.D=def;
    	if(mon.S&2) def=0;
    	if(atk<=mon.D) return 0ll;
    
    	int dps=atk-mon.D, mon_dps=mon.A<=def?0:mon.A-def;
    	int tm=(mon.S&4)?2:1;
    	LL hpbef=hp; hp+=mdf;
    	if(mon.S&1) hp-=mon_dps*tm;
    
    	hp-=1ll*mon_dps*tm*((mon.H+dps-1)/dps-1);
    	return hp>hpbef?hpbef:hp;
    }
    
    int main()
    {
    	pw[0]=1;
    	for(int i=1; i<=14; ++i) pw[i]=pw[i-1]*3;
    	for(int i=1; i<=14; ++i) bit[1<<i]=i;
    	for(int T=read(); T--; )
    	{
    		memset(ok,0,sizeof ok), memset(f,0,sizeof f);
    		int Hp=read(), Atk=read(), Def=read(), Mdf=read();
    		int n=read();
    		for(int i=0; i<n; ++i) A[i]=(Monster){read(),read(),read(),read(),read(),read(),read(),read()};
    		for(int K=read(); K--; ) ok[read()-1]|=1<<(read()-1);
    
    		int tot=(1<<n)-1;
    		for(int s=0; s<=tot; ++s)
    		{
    			sap[s]=Atk, sdp[s]=Def, smp[s]=Mdf;
    			for(int i=0; i<n; ++i) if(s>>i&1) sap[s]+=A[i].ap, sdp[s]+=A[i].dp, smp[s]+=A[i].mp;
    		}
    		int lim=pw[n]-1; f[0]=Hp;
    		for(int s=0; s<lim; ++s)
    		{
    			if(!f[s]) continue;//!
    			int S1=s1[s], S2=s2[s];
    			for(int i=S1^tot,j; i; i^=lb(i))
    			{
    				j=bit[lb(i)];
    				if((S1&ok[j])!=ok[j]) continue;
    				f[s+pw[j]]=std::max(f[s+pw[j]],Combat(A[j],f[s],sap[S2],sdp[S2],smp[S2]));
    				s1[s+pw[j]]=S1|(1<<j), s2[s+pw[j]]=S2;
    			}
    			for(int i=S1^S2,j; i; i^=lb(i))
    			{
    				j=bit[lb(i)];
    				f[s+pw[j]]=std::max(f[s+pw[j]],f[s]+A[j].hp);
    				s1[s+pw[j]]=S1, s2[s+pw[j]]=S2|(1<<j);
    			}
    		}
    		printf("%lld
    ",f[lim]?f[lim]:-1ll);
    	}
    	return 0;
    }
    

    B 奇迹暖暖

    题目链接

    
    

    C 风花雪月(DP)

    题目链接

    见:https://www.cnblogs.com/SovietPower/p/9862098.html。

    考试代码

    A

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    const int N=17,M=205;
    
    int n,lim,K,Atk,Def,Mdf,dgr[N],Enum,H[N],nxt[M],to[M];
    LL Hp,Ans,mx[(1<<15)+2];
    struct Monster
    {
    	int H,A,D,S,ap,dp,mp,hp;
    }A[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline void AddEdge(int v,int u){
    	++dgr[v], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    }
    inline bool Can(int x,int s)
    {
    	for(int i=H[x]; i; i=nxt[i]) if(!((s>>to[i]-1)&1)) return 0;
    	return 1;
    }
    inline LL Kill(Monster mon,LL hp,int atk,int def,int mdf)
    {
    	if(mon.S>>3&1) mon.A=atk, mon.D=def;
    	if(mon.S>>1&1) def=0;
    	if(atk<=mon.D) return 0ll;
    
    	int dps=atk-mon.D, mon_dps=mon.A<=def?0:mon.A-def;
    	int tm=(mon.S>>2&1)?2:1;
    	LL hpbef=hp; hp+=mdf;
    	if(mon.S&1) hp-=mon_dps*tm;
    
    	hp-=1ll*mon_dps*tm*((mon.H+dps-1)/dps-1);
    	return hp>hpbef?hpbef:hp;
    }
    void DFS(int s,LL hp,int atk,int def,int mdf)
    {
    	if(mx[s]>=hp) return;
    	if(s==lim) {mx[s]=hp, Ans=std::max(Ans,hp); return;}
    
    	LL tmp=hp;
    	for(int i=0; i<n; ++i) if(!(s>>i&1)) tmp+=A[i+1].hp;
    	if(tmp<=mx[s]) return;
    
    	for(int i=n; i; --i)
    		if(!((s>>i-1)&1) && !dgr[i] && (tmp=Kill(A[i],hp,atk,def,mdf))>0)
    		{
    			for(int j=H[i]; j; j=nxt[j]) --dgr[to[j]];
    			DFS(s|(1<<i-1),tmp+A[i].hp,atk+A[i].ap,def+A[i].dp,mdf+A[i].mp);
    			for(int j=H[i]; j; j=nxt[j]) ++dgr[to[j]];
    		}
    }
    
    int main()
    {
    //	freopen("A.in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	for(int T=read(); T--; )
    	{
    		Ans=-1ll, Enum=1, memset(H,0,sizeof H), memset(mx,0,sizeof mx), memset(dgr,0,sizeof dgr);
    		Hp=read(), Atk=read(), Def=read(), Mdf=read();
    		n=read(), lim=(1<<n)-1;
    		for(int i=1; i<=n; ++i) A[i]=(Monster){read(),read(),read(),read(),read(),read(),read(),read()};
    		K=read();
    		for(int i=1; i<=K; ++i) AddEdge(read(),read());
    		DFS(0,Hp,Atk,Def,Mdf);
    		printf("%lld
    ",Ans);
    	}
    	return 0;
    }
    

    B

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    const int N=101;
    
    int n,m,c;
    LL Ans;
    struct Event
    {
    	int l,r,x,y;
    }A[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    void DFS(int now,int rest,LL w)
    {
    	if(!rest||now>n) {Ans=std::max(Ans,w); return;}
    	int X[6]; LL tmp;
    	for(int i=1; i<=m; ++i) X[i]=A[i].x;
    	DFS(now+1,rest,w);
    	for(int x=1; x<=rest; ++x)
    	{
    		tmp=0;
    		for(int i=1; i<=m; ++i)
    			if(A[i].l<=now&&A[i].r>=now&&A[i].x>0)
    				tmp+=std::min(A[i].x,x)*A[i].y, A[i].x-=x;
    		DFS(now+1,rest-x,w+tmp);
    		for(int i=1; i<=m; ++i) A[i].x=X[i];
    	}
    }
    void DFS2(int now,int rest,LL w)
    {
    	if(!rest||now>n) {Ans=std::max(Ans,w); return;}
    	int X[N]; LL tmp;
    	for(int i=1; i<=m; ++i) X[i]=A[i].x;
    	DFS2(now+1,rest,w);
    	for(int x=1; x<=rest; ++x)
    	{
    		tmp=0;
    		for(int i=1; i<=m; ++i)
    			if(A[i].l<=now&&A[i].r>=now&&A[i].x>0)
    				tmp+=std::min(A[i].x,x)*A[i].y, A[i].x-=x;
    		DFS2(now+1,rest-x,w+tmp);
    		for(int i=1; i<=m; ++i) A[i].x=X[i];
    	}
    }
    
    int main()
    {
    //	freopen("B2.in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	n=read(), m=read(), c=read();
    	for(int i=1; i<=m; ++i) A[i]=(Event){read(),read(),read(),read()};
    	if(n<=5) DFS(1,c,0);
    	else DFS2(1,c,0);
    	printf("%lld
    ",Ans);
    
    	return 0;
    }
    

    C

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    #define INF (1e6)
    #define mod (1000000007)
    typedef long long LL;
    const int N=12;
    
    int n,Sum,p[N],Q,c[N],have[N],Max,tot;
    
    struct Fraction
    {
    	LL x,y;
    	Fraction() {x=0, y=1;}
    	Fraction(LL x,LL y):x(x),y(y) {}
    
    	void Debug() {printf("%lld/%lld
    ",x,y);}
    	LL Gcd(LL x,LL y) {return y?Gcd(y,x%y):x;}
    	inline void Fix() {LL g=Gcd(x,y); x/=g,y/=g;}
    	void Exgcd(LL a,LL b,LL &x,LL &y)
    	{
    		if(!b) x=1, y=0;
    		else Exgcd(b,a%b,y,x), y-=a/b*x;
    	}
    	void Output()
    	{
    		if(y==1) {printf("%lld
    ",x); return;}
    		LL inv,b;
    		Exgcd(y,mod,inv,b);
    		printf("%lld
    ",inv*x%mod);
    	}
    	friend bool operator <(const Fraction &f,const Fraction &g)
    	{
    		return f.x*g.y<g.x*f.y;
    	}
    	friend Fraction operator +(const Fraction &f,int num)
    	{
    		Fraction res=Fraction(f.x+f.y*num,f.y);
    		res.Fix();
    		return res;
    	}
    	friend Fraction operator +(const Fraction &f,const Fraction &g)
    	{
    		Fraction res=Fraction(f.x*g.y+g.x*f.y,f.y*g.y);
    		res.Fix();
    		return res;
    	}
    	friend Fraction operator *(const Fraction &f,int num)
    	{
    		Fraction res=Fraction(f.x*num,f.y);
    		res.Fix();
    		return res;
    	}
    	friend Fraction operator *(const Fraction &f,const Fraction &g)
    	{
    		Fraction res=Fraction(f.x*g.x,f.y*g.y);
    		res.Fix();
    		return res;
    	}
    }Ans,f[1000003];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline LL FP(LL x,int k)
    {
    	LL t=1;
    	for(; k; k>>=1, x=x*x%mod)
    		if(k&1) t=t*x%mod;
    	return t;
    }
    bool Check(int now,Fraction res)
    {
    	int rest=0;
    	for(int i=1; i<=n; ++i)
    		if(have[i]>=c[i]) rest+=have[i]-c[i];
    	for(int i=1; i<=n; ++i)
    		if(have[i]<c[i])
    			if(rest>=4*(c[i]-have[i])) rest-=(c[i]-have[i]<<2);
    			else return 0;
    	if(rest) return 1;
    	putchar('
    '); Ans.Debug();puts("+=");res.Debug();
    	printf("Number: "); for(int i=1; i<=n; ++i) printf("%d ",have[i]); putchar('
    ');putchar('
    ');
    	Ans=Ans+res, ++tot;
    	return 1;
    }
    void DFS(int now,Fraction res)
    {
    //	printf("now:%d ",now), res.Debug();
    	if(Check(now,res)||now>n) return;
    	int mx=(Sum-c[now])*4+c[now];
    //	printf("mx:%d
    ",mx);
    	Fraction tmp=Fraction(Q,p[now]);
    	for(int i=0; i<=mx; ++i)
    		have[now]=i, printf("%d Chose %d:",now,i), (tmp*i).Debug(), DFS(now+1,std::max(tmp*i,res)), have[now]=0;
    }
    
    int main()
    {
    	freopen("C1.in","r",stdin);
    //	freopen(".out","w",stdout);
    
    	n=read();
    	for(int i=1; i<=n; ++i) Q+=(p[i]=read());
    	for(int i=1; i<=n; ++i) Sum+=(c[i]=read());
    	DFS(1,Fraction(0,1));
    	(Ans*Fraction(1,tot)).Output();
    
    	return 0;
    }
    
  • 相关阅读:
    「B/S端开发」如何将DevExtreme组件添加到React应用程序?
    完整UI组件库Kendo UI for Vue R3 2021
    DevExpress WPF界面控件
    DevExpress WinForm MVVM数据和属性绑定指南(Part 1)
    界面控件Telerik UI for WinForm初级教程
    ua-parser-js 实现获取浏览器信息和操作系统信息
    vue--axios 拦截器的简单介绍及使用场景
    css 插件
    去除List集合中的重复值(四种好用的方法)
    常州大学/企业微信/电费查询脚本
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9448244.html
Copyright © 2011-2022 走看看