151013总结

t1

听说是道dp?于是我搜了过去

其实还是用到了记忆化dp的思想

这道题值得反思的是:

1.错误信息打错

2.数组没开够

第一点少了37.5分,第二点少开了1,不过傲娇的评测机并没有判我RE

67.5 以后注意读题啊

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
inline void R(int &v)
{
	v=0;char c=0;int p=1;
	while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
	while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
	v*=p;
}
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
bool can[1001][3001];
bool visit[1001][3001];
int n;
int a[1001],b[1001];
int _time[3000005];
pair<int,int>que[3000005];
int main()
{
	freopen("river.in","r",stdin);
	freopen("river.out","w",stdout);
	R(n);
	for(int i=1;i<=n;i++)
	{
		R(a[i]),R(b[i]);
	}
	for(int i=1;i<=2520;i++)can[0][i]=true;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=2521;j++)
		{
			if((j-1)%(a[i]+b[i])+1<=a[i])can[i][j]=true;
		}
	}
	que[1]=make_pair(0,0);
	int head=0,tail=1;
	while(head!=tail)
	{
		head++;
		int x=que[head].first,y=que[head].second;
		for(int i=x-5;i<=x+5;i++)
		{
			if(i<0)continue;
			if(i>n)printf("%d\n",_time[head]+1),exit(0);
			if(!visit[i][y+1] && can[i][y+1])
			{
				visit[i][y+1]^=1;
				que[++tail]=make_pair(i,y+1);
				_time[tail]=_time[head]+1;
			}
		}
	}
	printf("NO\n");
	return 0;
}
T2

调试一下午,状压dp+单调栈维护搜索+启发式打表+黑科技剪枝

然后就20了,再次读错输出信息,又手贱打了个偏分,直接少50分 20

T3

NOI2014 D2T1

看到100w吓尿了。。想了好久写了个bfs+lca+倍增,各种黑科技减常数,最终搞定

考场上70

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
#define mod 1000000007ll
//using namespace std;
inline void R(int &v)
{
	v=0;char c=0;int p=1;
	while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
	while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
	v*=p;
}
int next[1000010];
char s[1000010];
int deep[1000010];
int jump[1000010][21];
struct Edge
{
	int to;
	int next;
}edge[1000010];
int first[1000010],size;
int dl[1000010];
void addedge(int x,int y)
{
	size++;
	edge[size].to=y;
	edge[size].next=first[x];
	first[x]=size;
}
void bfs()
{
	int head=0,tail=1;
	while(head!=tail)
	{
		head++;
		deep[dl[head]]=deep[next[dl[head]]]+1;
		jump[dl[head]][0]=next[dl[head]];
		for(int i=1;i<=20;i++)jump[dl[head]][i]=jump[jump[dl[head]][i-1]][i-1];
		for(int u=first[dl[head]];u;u=edge[u].next)dl[++tail]=edge[u].to;
	}
}
int main()
{
	freopen("zoo.in","r",stdin);
	freopen("zoo.out","w",stdout);
	int T;R(T);
	while(T--)
	{
		scanf("%s",s+1);
		int len=strlen(s+1);
		next[1]=0;
		int now=0;
		for(int i=2;i<=len;i++)
		{
			while(now&&s[now+1]!=s[i])now=next[now];
			if(s[now+1]==s[i])now++;
			next[i]=now;
		}
		memset(first,0,sizeof first);
		size=0;
		for(int i=1;i<=len;i++)addedge(next[i],i);
		deep[0]=0;
		//cerr<<"s"<<clock()<<endl;
		bfs();
		//cerr<<"e"<<clock()<<endl;
		ll ans=1;
		for(int i=1;i<=len;i++)
		{
			if(next[i]<=(i>>1)){ans=(ans*(ll)(deep[i]-1))%mod;continue;}
			int now=i;
			for(int j=20;j>=0;j--)
			{
				if(jump[now][j]>(i>>1))now=jump[now][j];
			}
			ans=(ans*(ll)(deep[now]-1))%mod;
		}
		std::cout<<ans<<std::endl;
		//for(int i=1;i<=len;i++)printf("%d ",next[i]);
		//cerr<<clock()<<endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值