hdu2296
来源:互联网 发布:光纤网络布线方案 编辑:程序博客网 时间:2024/05/22 00:49
今天机房断网,结果回来才交果不其然WA掉了。然后又是各种调各种弄,最后竟然A了。真是畸形。个人觉得字符串上的DP基本都是按照字符串的位进行的。当然我也没有做几道题。这个也是一个很简单的DP但是对于预处理方面可能需要考虑一下,以及它最后的要求是输出字典序最小。而且之前也没有看到最后答案可能会有空串什么的,改了就过了。
上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
struct node{
node *fail;
node *next[26];
int count;
int id;
bool end;
int v;
int ss;
node(){
id=0;
end=false;
fail=NULL;
count=0;
v=0;
for(int i=0;i<=25;i++)
next[i]=NULL;
}
};
struct sstring{
char s1[60];
};
sstring s[1110];
bool cmp(sstring a, sstring b){
if(strlen(a.s1)==strlen(b.s1))
return strcmp(a.s1,b.s1)<0;
return strlen(a.s1)<strlen(b.s1);
}
const int MAXN=1110;
node *T[1110];
node *q[MAXN];
node *root=new node();
int num=1;
void insert(char word[],int value){
node *cur=root;
int i=0,branch;
while(word[i]){
branch=word[i]-'a';
if(cur->next[branch]==NULL){
cur->next[branch]=new node();
T[num]=cur->next[branch];
T[num]->ss=branch;
cur->next[branch]->id=num++;
}
i++;
cur=cur->next[branch];
}
cur->v=value;
cur->end=true;
cur->count++;
}
void AC(){
int rear=1,front=0,i;
node *cur;
q[0]=root;
root->fail=root;
while(front!=rear){
node *p=q[front++];
p->end=p->end||p->fail->end;
for(int i=0;i<=25;i++){
if(p->next[i]==NULL){
if(p==root)
p->next[i]=root;
else
p->next[i]=p->fail->next[i];
}
else{
if(p==root)
p->next[i]->fail=root;
else{
p->next[i]->fail=p->fail->next[i];
}
q[rear++]=p->next[i];
}
}
}
}
char a[110][20];
int dp[60][1110];
int pre[60][1110];
int g[MAXN][MAXN];
int vis[60][1110];
main(){
int t,n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
root=new node();
num=1;
for(int i=1;i<=m;i++){
scanf("%s",a[i]);
}
for(int i=1;i<=m;i++){
int cnt;
scanf("%d",&cnt);
insert(a[i],cnt);
}
AC();
T[0]=root;
root->id=0;
root->ss=30;
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
memset(vis,0,sizeof(vis));
for(int k=0;k<=25;k++){
if(T[0]->next[k]!=NULL){
if(T[0]->next[k]->id!=0){
dp[1][T[0]->next[k]->id]=T[0]->next[k]->v;
vis[1][T[0]->next[k]->id]=1;
}
}
}
dp[1][0]=0;
for(int i=1;i<=n-1;i++){
for(int j=0;j<num;j++){
if(vis[i][j]){
for(int k=0;k<=25;k++){
if(T[j]->next[k]!=NULL){
if(dp[i+1][T[j]->next[k]->id]<=dp[i][j]+T[j]->next[k]->v){
vis[i+1][T[j]->next[k]->id]=1;
if(dp[i+1][T[j]->next[k]->id]==(dp[i][j]+T[j]->next[k]->v) && dp[i+1][T[j]->next[k]->id]!=0){
int p=j;
char pp[2][20];
pp[0][i]=0;
for(int kk=i-1;kk>=0;kk--){
pp[0][kk]=T[p]->ss+'a';
p=pre[kk+1][p];
}
p=pre[i+1][T[j]->next[k]->id];
pp[1][i]=0;
for(int kk=i-1;kk>=0;kk--){
pp[1][kk]=T[p]->ss+'a';
p=pre[kk+1][p];
}
if(strcmp(pp[0],pp[1])<0)
pre[i+1][T[j]->next[k]->id]=j;
}
else{
pre[i+1][T[j]->next[k]->id]=j;
dp[i+1][T[j]->next[k]->id]=dp[i][j]+T[j]->next[k]->v;
}
}
}
}
}
}
}
int nnum=0;
int maxx=0;
for(int i=1;i<=n;i++){
for(int j=0;j<num;j++){
//printf("%d ",dp[i][j]);
if(dp[i][j]>maxx){
maxx=dp[i][j];
}
}
}
for(int j=1;j<=n;j++){
for(int i=0;i<num;i++){
if(dp[j][i]==maxx){
int p=i;
s[nnum].s1[j]=0;
for(int k=j-1;k>=0;k--){
s[nnum].s1[k]=T[p]->ss+'a';
p=pre[k+1][p];
}
nnum++;
}
}
}
sort(s,s+nnum,cmp);
if(maxx==0)
printf("\n");
else
printf("%s\n",s[0].s1);
}
}
- hdu2296
- hdu2296
- hdu2296 Ring
- HDU2296 Ring
- HDU2296-Ring
- hdu2296 AC自动机
- AC自动机+DP+hdu2296
- hdu2296(AC自动机+DP)
- hdu2296 AC自动机+DP
- HDU2296--Ring--AC自动机+DP
- hdu2296---Ring(AC自动机+dp)
- HDU2296 Ring AC自动机+DP
- hdu2296 Ring (AC自动机+dp)
- hdu2296-(AC自动机+DP)
- HDU2296(AC自动机+DP)
- AC自动机+dp打印路径 hdu2296 Ring
- hdu2296||UVALive 4223 Trucking (二分+spfa)
- ORA-04031错误的解决思路
- windowsphone7 消息推送Demo
- 关于windows64位与32位操作系统的浅见(初学者,第一篇博客)
- 为什么基类指针指向派生类是安全的,而派生类指向基类则是不安全的
- Android 实现异步加载图片
- hdu2296
- c语言字符串函数
- Algorithms 学习笔记05 Priority Queues
- 2012最受企业欢迎的开发技能Top10
- 9.在JDBC中应用ORACLE
- XCode4中的story board的研究
- C#学习1
- Linux 设备驱动开发 —— 基于自己的设备驱动开发环境设计驱动(一)
- 诠释全外连接、左外连接、右外连接、以及它们之间的区别