【比赛报告】非酋yyf的sif之旅 NOIP练习赛卷八

比赛链接
赛后题解

A.yyf hates ganhuodong

题目链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


#include<cstdio>
int a,b,c,d,e,f,g,h,k,x,y;
int pt,lp,exp;
int main()
{
	//freopen("in.txt","r",stdin);
	scanf("%d%d%d%d%d%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f,&g,&h,&k,&x,&y);
	pt=0,lp=d+x,exp=f;
	long long cnt=0;
	while(pt<y)
	{
		while(lp<b)cnt++,lp+=c;
		lp-=b;pt+=a;exp+=g;
		if(exp>=e)//没加等号,只有96 
		{
			exp-=e;
			e+=k;c+=h;lp+=c;
		}
	}
	printf("%lld\n",cnt);
	return 0;
}

总结

很水一题,据说是贪心……个人感觉倒像个模拟
我会告诉你我比赛时被卡了等号没有AC吗


B.yyf hates choukapai

题目链接
在这里插入图片描述
在这里插入图片描述


赛后题解

#include<cstdio>
const int M=8e4+5,C=3e3+5,N=45,S=N*C+M;
int a[S],b[S],n,m,c,d,sum,hd[N],tl[N],s,q[N][S][2],f[S][N],p[S][N],pos[N],ans,Pos;
//f[i][j]前i张牌连抽j次 p[i][j]记录f[i][j]由哪个i转移过来 
int main()
{
	//freopen("in.txt","r",stdin);
    scanf("%d%d%d%d",&n,&m,&c,&d);s=n*c+m;
    for(int i=1;i<=s;i++)
        scanf("%d",&a[i]),sum+=a[i];
    for(int i=2;i<=c;i++)
        b[1]+=a[i];
    for(int i=2;i<=s-c+1;i++)
        b[i]=b[i-1]-a[i]+a[i+c-1];//b[i]维护a[i+1]加到a[i+c-1] 
    for(int i=1;i<=n;i++)
        hd[i]=1;
    for(int i=1;i<=s-c+1;i++)
    {
    	if(i<=c){f[i][1]=b[i];continue;}
    	for(int j=(i+c-2)/(c+d)+1;j<=(i+c-1)/c&&j<=n;j++)
    	{
    		if(hd[j-1]<=tl[j-1]&&q[j-1][hd[j-1]][1]<i-c-d)//队头超出范围的出队 
    		    hd[j-1]++;
    		if(j-1>=(i-2)/(c+d)+1&&j-1<=(i-1)/c)
    		{//能入队的入队 
    			while(hd[j-1]<=tl[j-1]&&q[j-1][tl[j-1]][0]>=f[i-c][j-1])
    			    tl[j-1]--;
    			q[j-1][++tl[j-1]][0]=f[i-c][j-1];//0记录的最大值 
    			q[j-1][tl[j-1]][1]=i-c;//1记录的位置 
			}
			f[i][j]=q[j-1][hd[j-1]][0]+b[i];
			p[i][j]=q[j-1][hd[j-1]][1];
			if(i>=s-c+1-d&&j==n&&ans<sum-f[i][j])
			    ans=sum-f[i][j],Pos=i;
		}
	}
	printf("%d\n",ans);
	for(int j=n;j;j--)
	    pos[j]=Pos,Pos=p[Pos][j];
	for(int i=1;i<=n;i++)
	    printf("%d ",pos[i]);
	puts("");
	return 0;
}

总结

当时好像是写了个0分的DP还是啥的,心态直接炸了,T3也没咋写就放弃了。自己的心态还是得练练,毕竟以后写不来的比赛题多了去了(笑)
自己动态规划太菜,这种状态转移方程都毫无头绪。状态转移方程出来单调队列就显而易见了。


C.yyf hates dagequ

题目链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


赛后题解
参考大佬题解

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e3+10;
int n,score,judge,minn,maxn;
double P[65][10],per[2][N][6],f[2][N][6],ans,add[65];
//f[i][j][k]表示第i个节奏打了j个combo之后k个节奏改判的期望得分
//per[i][j][k]表示转移到f[i][j][k]的概率 
bool to[2][N][6];
//to[i][j][k]表示f[i][j][k]是否转移过 
struct node{
	int c,p,t;//c次概率p%持续t 
	bool operator <(const node&rhs)const{
	return t>rhs.t;}
}gai[N];
int main()
{
	//freopen("in.txt","r",stdin);
    scanf("%d%d%d",&n,&score,&judge);
    int c,p,s;
	for(int i=1;i<=score;i++)
    {
    	scanf("%d%d%d",&c,&p,&s);//c次概率p%加s分 
    	for(int j=c;j<=60;j+=c)
    	    add[j]+=1.000000*(double)(p*s)/100.000000;//当连击数为j时期望加分 
	}
	for(int i=1;i<=judge;i++)
	    scanf("%d%d%d",&gai[i].c,&gai[i].p,&gai[i].t);
	sort(gai+1,gai+judge+1);P[0][0]=1.0;
	for(int i=1;i<=60;i++)//60是1~5的lcm 
	{
		double a=1.000000;
		for(int j=1;j<=judge;j++)
		{
			if(i%gai[j].c)continue;
			P[i][gai[j].t]+=a*(double)gai[j].p/100.000000;
			//combo为i时使用长度为gai[j].c的改判的概率大小
			a=(a*(double)(100-gai[j].p))/100.000000;//没有用 
		}
		P[i][0]=a;//没有效果的概率 
	}
	to[0][0][0]=1;per[0][0][0]=1.000000;
	for(int i=0,o=1,t=0;i<n;i++)
	{
		//t的状态转移到o的状态 
		int po;maxn=0;
		scanf("%d",&po);//第i次击打的原始结果 
		memset(f[o],0,sizeof(f[o]));
		memset(per[o],0,sizeof(per[o]));
		memset(to[o],0,sizeof(to[o]));
		for(int j=0;j<=minn;j++)
		    for(int k=0;k<6;k++)
		    {
		    	if(!to[t][j][k])continue;//没有转移过
				int co=(j+(po+k>=2))*(po>1||(k&&po));//combo数 
			    int sp=(co-1)%60+1;//得到combo数对应循环节中位置
				for(int l=0;l<6;l++)
				{
					if(!P[sp][l])//combo为sp,长度为l
					    continue;
					int m=(k-1)>l?(k-1):l;//最长持续时间 
					int poi=min(2,po+(k>0&&po));//改判后的结果
					f[o][co][m]+=(f[t][j][k]+(add[sp]+(double)(co+1)*poi)*per[t][j][k])*1.000000*P[sp][l];
					per[o][co][m]+=per[t][j][k]*P[sp][l];
					to[o][co][m]=1;
					maxn=max(maxn,co);
				}
			}
		minn=maxn;swap(o,t);
	}
	for(int i=0;i<=n;i++)
	    for(int j=0;j<6;j++)
	        ans+=f[n&1][i][j];
	printf("%.6f\n",ans);
	return 0;
}

总结

当时没有做第三题。这个期望DP还是比较厉害的,有很多需要注意的地方和优化。阿福又学会了新招。


赛后总结

这篇比赛最精华的是后面两道DP题。T2是一个单调队列优化DP,说难呢也不是真的很难,但是自己确实不会写。T3期望DP的大佬操作很厉害,好好看好好学。
自己动态规划写的很不好,可以考虑再写一两场比赛就去补专题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值