「百度之星」最强密码
题解
yy一下构建出一张图,即每个结点加个字母能转移到另一个结点
然后递推一下即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#include<map> #include<set> #include<cmath> #include<ctime> #include<queue> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define inf 1000000000 #define mod 1000000007 #define ll long long using namespace std; int read() { int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int T,n; int f[100005],g[100005]; char a[100005]; vector<int>e[100005]; int main() { T=read(); int cas=0; while(T--) { cas++; printf("Case #%d:\n",cas); scanf("%s",a+1); n=strlen(a+1); for(int i=0;i<=n+1;i++)e[i].clear(),f[i]=inf,g[i]=0; for(int i=1;i<=26;i++) { char c=i+'a'-1; int last=n+1; for(int j=n;j>=0;j--) { e[j].push_back(last); if(a[j]==c)last=j; } } f[0]=0;g[0]=1; for(int i=0;i<=n+1;i++) { for(int j=0;j<e[i].size();j++) { if(f[i]+1<f[e[i][j]])f[e[i][j]]=f[i]+1,g[e[i][j]]=0; if(f[i]+1==f[e[i][j]])g[e[i][j]]+=g[i],g[e[i][j]]%=mod; } } printf("%d %d\n",f[n+1],g[n+1]); } return 0; } |
大神,你这个节点是什么意思?求详细解释一下,谢谢啦
当前匹配位置
哦哦,对的,这个题已经搞懂了,感觉真是神DP,当时比赛的时候没看出来。。。太弱了23333