【比赛报告】2018.10.19 NOIP练习赛卷十九

比赛时间:2018.10.19 选手:lrllrl 用时:2.5h 得分:10+0+30=40


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,a[1010][1010],dp[1010][1010][2],pre[1010][1010];
int num(int i,int j){return (i-1)*m+j;}
int main()
{
	freopen("lemouse.in","r",stdin);
	freopen("lemouse.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++)
	        scanf("%d",&a[i][j]);
	memset(dp,0x3f,sizeof(dp));
	dp[0][1][0]=dp[1][0][0]=dp[1][0][1]=dp[0][1][1]=a[1][1];
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++)
	    {
	    	dp[i][j][0]=min(dp[i-1][j][0]+a[i][j-1],dp[i-1][j][1])+a[i][j+1]+a[i+1][j];
	    	dp[i][j][1]=min(dp[i][j-1][1]+a[i-1][j],dp[i][j-1][0])+a[i][j+1]+a[i+1][j];
		}
	printf("%d\n",min(dp[n][m][0],dp[n][m][1]));
	return 0;
}

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e4+10;
const int INF=0x3f3f3f3f;
int n,m,hd[N],r[N],tot,nowrank,dis[N],lim[N],stack[N],tp,top,ans,minr[N];
struct Edge{
	int v,w,nx;
}e[N*10];
struct Heap{
	int x,w;
	Heap(void){}
	Heap(int _x,int _w):x(_x),w(_w){}
}heap[100*N];
void add(int u,int v,int w)
{
	e[++tot].v=v;
	e[tot].w=w;
	e[tot].nx=hd[u];
	hd[u]=tot;
}
bool cmp(const Heap&a,const Heap&b)
{
	return a.w>b.w||(a.w==b.w&&r[a.x]<r[b.x]);
}
void dijk()
{
	while(top)
	{
		Heap sta=heap[1];
		pop_heap(heap+1,heap+top+1,cmp);
		top--;
		if(sta.w!=dis[sta.x])continue;
		stack[++tp]=sta.x;
		for(int i=hd[sta.x];i;i=e[i].nx)
		{
			if(r[e[i].v]>nowrank)continue;
			if(dis[e[i].v]>sta.w+e[i].w&&lim[e[i].v]>sta.w+e[i].w)
			{
				dis[e[i].v]=sta.w+e[i].w;
				heap[++top]=Heap(e[i].v,dis[e[i].v]);
				push_heap(heap+1,heap+top+1,cmp);
			}
		}
	}
}
int main()
{
	freopen("serves.in","r",stdin);
	freopen("serves.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	    scanf("%d",&r[i]);
	for(int i=1,u,v,w;i<=m;i++)
	    scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
	memset(dis,0x3f,sizeof(dis));
	memset(lim,0x3f,sizeof(lim));
	for(int i=10;i;i--)
	{
		nowrank=i;
		memset(minr,0x3f,sizeof(minr));
		for(int j=1;j<=n;j++)
		    if(r[j]==i)
		    {
		    	heap[++top]=Heap(j,0);
		    	dis[j]=0;
		    	dijk();
		    	for(;tp;tp--)
		    	{
		    		int k=stack[tp];
		    		if(lim[k]>dis[k])ans++;
		    		minr[k]=min(minr[k],dis[k]);
		    		dis[k]=INF;
				}
			}
		for(int j=1;j<=n;j++)
		    lim[j]=min(minr[j],lim[j]);
	}
	printf("%d\n",ans);
	return 0;
}

在这里插入图片描述


在这里插入图片描述

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1000010;
const ull mul=1333331;
int n,m,a[N],b[N],X[N],k;
ull hx[N],f[N]={1};
ll ans;
inline int bin(int x)
{
	int l=1,r=k;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(b[mid]<=x)l=mid+1;
		else r=mid-1;
	}
	return r;
}
inline ull getHash(const int &l,const int &r)
{
	return hx[r]-hx[l-1]*f[r-l+1];
}
inline int lcp(int x,int y)//求最长公共后缀 
{
	int l=0,r=min(n-x+1,n-y+1);
	while(l<=r)
	{
		int mid=l+r>>1;
		if(getHash(x,x+mid-1)==getHash(y,y+mid-1))l=mid+1;
		else r=mid-1;
	}
	return r;
}
inline int anti_lcp(int x,int y)
{
	int l=0,r=min(x,y);
	while(l<=r)
	{
		int mid=l+r>>1;
		if(getHash(x-mid+1,x)==getHash(y-mid+1,y))l=mid+1;
		else r=mid-1;
	}
	return r;
}
int main()
{
	freopen("weapon.in","r",stdin);
	freopen("weapon.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	    scanf("%d",&a[i]),X[i]=a[i];
    sort(X+1,X+n+1);
    X[0]=~0U>>1;
    for(int i=1;i<=n;i++)
        if(X[i]!=X[i-1])
            b[++k]=X[i];
    for(int i=1;i<=n;i++)
        a[i]=bin(a[i]);
    for(int i=1;i<=n;i++)
        f[i]=f[i-1]*mul;
    for(int i=1;i<=n;i++)
        hx[i]=hx[i-1]*mul+a[i];
    for(int i=1;2*i+m<=n;i++)
    {
    	int nowl=0;
    	for(int j=1;;)
    	{
    		int len=min(i,n-(j+i+m-1));
    		if(!len)break;
    		int frontl=lcp(j,j+i+m);
    		int backl=anti_lcp(j+len-1,j+m+i+len-1);
    		frontl=min(frontl,len);
    		backl=min(backl,len);
    		if(frontl==len)
    		{
    			if(nowl>=i)ans+=len;
    			else ans+=max(0,nowl+frontl-i+1);
    			nowl+=len;
			}
			else
			{
				if(nowl>=i)ans+=frontl;
				else ans+=max(0,nowl+frontl-i+1);
				nowl=backl;
			}
			j+=len;
		}
	}
	cout<<ans<<endl;
	return 0;
}

赛后总结

T1很傻逼的在那里大力分类讨论……这种DP多开一两维不是正常操作吗,这都想不到,DP实在太弱
T2一脸不可做,T3一脸不可做
总体来说自己还是太弱了,不要再颓了

猜你喜欢

转载自blog.csdn.net/qq_41958841/article/details/83311287