Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:g++内存超、C++普通 DP超时?? 还是换成最短路过的,真菜--

Posted by ym94 at 2019-08-19 11:41:38 on Problem 1732
In Reply To:Re:g++内存超、C++普通 DP超时?? 还是换成最短路过的,真菜-- Posted by:ym94 at 2019-08-19 11:41:15
AC代码:
#include<stdio.h>
#include<string.h>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#define Max 10100
#define inf 0x3f3f3f3f

using namespace std;
char s[110],t[110];
int min(int x,int y)
{
	if(x>y) return y;
	return x;
}
/* dp 没有*/
//int dp[105][1000];//
//int dp2[105][1000];
int table[]={2,2,2,3,3,3,4,4,1,1,5,5,6,6,0,7,0,7,7,8,8,8,9,9,9,0}; 
int Nxt[110];  //KMP
int Num[110];  //用来保存路径 
stack <int> ss;
map<int,string> m;
bool vis[110];
int dist[110];
int max_num;
struct Edge{
	int next;  //指向下一个元素 
	int to;  //点 
	int dis;//距离 
	int id;
}edge[100000];
int num_edge;
int head[110];//初始化为0 
void add_edge(int x,int y,int data,int id)  //头插法 
{
	edge[++num_edge].next=head[x];
	edge[num_edge].to=y;
	edge[num_edge].dis=data;
	edge[num_edge].id=id;
	head[x]=num_edge;
}
struct heap{ //构建优先队列
	int data;
	int weight;
};
struct cmp{  //优先队列 比较函数
 bool operator()(struct heap a,struct heap b)
	{
		return a.weight>b.weight;
	}
};
priority_queue <struct heap,vector<heap>,cmp> q;
int n;
void dijkstra(int num)  //模板咯 
{
	dist[num]=0;
	struct heap h;
	h.data=num;
	h.weight=0;
	num_edge=0;
	q.push(h);
	while(q.size())
	{
		int min=inf,u=-1;
		h=q.top();
		q.pop();
		min=h.weight;
		u=h.data;
		if(vis[u])
			continue;
		vis[u]=true;
		for(int i=head[u];i;i=edge[i].next)
		{
			if(min+edge[i].dis<dist[edge[i].to])
			{
				dist[edge[i].to]=min+edge[i].dis;
				Num[edge[i].to]=edge[i].id;  //记录边同dp 操作 
				if(vis[edge[i].to]) 
				continue;
				h.data=edge[i].to;
				h.weight=dist[edge[i].to];
				q.push(h);
			}
		}
	}
}
/*dpGG了???KMP+dp c++ 超时 g++ 内存炸??*/
void  init()
{
	num_edge=0;
	memset(vis,false,sizeof(vis));
	memset(dist,inf,sizeof(dist));
	memset(head,0,sizeof(head));
}
void chang(char *s)  //变成数字 
{
	for(int i=0;s[i];i++)
		s[i]=table[s[i]-'a']+'0';
}
void KMP(char *s,char *t,int num)
{
	int m=strlen(t);
	Nxt[0]=-1;
	for(int i=1;i<m;i++)
	{
		int j=Nxt[i-1];
		while((t[j+1]!=t[i])&&(j>=0))
			j=Nxt[j];
		if(t[j+1]==t[i])
			Nxt[i]=j+1;
		else
			Nxt[i]=-1;
	}
	int i=0,j=0;
	int n=strlen(s);
	while(i<n)
	{
		if(s[i]==t[j])
		{
			i++;j++;
			if(j==m)
			{
				add_edge(i-m,i,1,num);
				/*dp 超时....卡常???*/
//			printf("%d %d %d \n",i-m,i,num) ;
//				dp[i-m][0]++; 	//记录 
//				dp[i-m][dp[i-m][0]]=i;
//				dp2[i-m][dp[i-m][0]]=num;
//				printf("%s :%d\n",t,i-m);
				j=Nxt[j-1]+1;
			}
		}
		else
		{
			if(j==0) i++;
			else j=Nxt[j-1]+1;
		}
	}
}
int main()
{
	int k,len,temp,cnt;
	char *abc;
	string nnm;
	while(scanf("%s",t)!=EOF)
	{
		scanf("%d",&k);
		init();//初始化 
		cnt=0;
		while(k--)
		{
			scanf("%s",s);
			++cnt;
			nnm=s;
			m[cnt]=nnm;  //map hash 
			chang(s);
			KMP(t,s,cnt);
		}
		dijkstra(0);
		while(ss.size()) ss.pop();
		for(int i=strlen(t);i>0;i--)
		{
			temp=Num[i];
			if(Num[i]!=0) ss.push(temp);  //因为是反着存的 
			else break;
			i=i-m[temp].length();
			i++; //抵消-- 
		}
		if(!ss.size()) printf("No solution.");
		while(ss.size())  //反着输出 
		{
			printf("%s",m[ss.top()].c_str());
			ss.pop();
			if(ss.size()) printf(" ");
		}
		printf("\n");
	}
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator