UVa 10029 hash + dp
第一次正式用hash表。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 25500; const int HASH = 1000003; char s[maxn][20]; int head[HASH],next[maxn]; int dp[maxn]; int n; char temp[20]; //变出来的字符串 int hash(char *s) { int seed = 131; int ret = 0; while(*s) { ret = ret * seed + *(s++); } return (ret & 0x7fffffff ) % HASH ; } void input() { n = 1; memset(head,-1,sizeof(head)); while(scanf("%s",s[n]) == 1) { int id = hash(s[n]); next[n] = head[id]; head[id] = n; n++; } n--; } int search() { int i; int id = hash(temp); for(i=head[id]; i!=-1; i=next[i]) { if(strcmp(temp,s[i]) == 0) break; } return i; } void add(int cur,int loc,int addnum) { int len = strlen(s[cur]); int i,j; for(i=0,j=0; i<loc; i++) { temp[j++] = s[cur][i]; } temp[j++] = 'a' + addnum; for(; i<len; i++) { temp[j++] = s[cur][i]; } temp[j] = '\0'; } void del(int cur,int loc) { int len = strlen(s[cur]); int i,j; for(i=0,j=0; i<loc; i++) temp[j++] = s[cur][i]; i++; for(; i<len; i++) temp[j++] = s[cur][i]; temp[j] = '\0'; } void change(int cur,int loc,int addnum) { strcpy(temp,s[cur]); temp[loc] += addnum; } int dfs(int cur) { if(dp[cur] != -1) return dp[cur]; int len = strlen(s[cur]); int ret = 0; //add; for(int i=0; i<=len; i++) { for(int j=0; j<26; j++) { add(cur,i,j); int id = search(); if(id!=-1 && strcmp(s[cur],temp) < 0) { ret = max(ret,dfs(id)+1); } } } //del; for(int i=0; i<len; i++) { del(cur,i); int id = search(); if(id != -1 && strcmp(s[cur],temp) < 0) ret = max(ret,dfs(id)+1); } //change; for(int i=0; i<len; i++) { int lim = 'z' - s[cur][i]; for(int j=1; j<=lim; j++) { change(cur,i,j); int id = search(); if(id != -1 && strcmp(s[cur],temp) < 0) ret = max(ret,dfs(id)+1); } } dp[cur] = ret; return ret; } void solve() { memset(dp,-1,sizeof(dp)); int ans = 0; for(int i=1; i<=n; i++) { ans = max(ans,dfs(i)); } printf("%d\n",ans+1); } int main() { // freopen("E:\\acm\\input.txt","r",stdin); input(); solve(); }