[关闭]
@ysner 2018-05-25T22:30:03.000000Z 字数 1556 阅读 2179

[APIO2008]DNA

DP


题面

戳我

解析

我们要求出第种方案,莫过于看其前面什么时候有种方案。
于是,我们要求出每种情况的方案数。
表示第个字母中,已分段,第个字母为s()字母的序号 的方案数。
状态转移方程易得:(其中是下一个字母)

为了下面运算方便,要对求前缀和
然后就可以从前往后推了,若碰到的字母已知,看是否影响段数就可以了;
如果碰到的字母未知,枚举的情况,如,说明第个还在当前枚举字母情况的后面,继续枚举;否则,这一位就应该填当前枚举到的字母。

  1. #include<iostream>
  2. #include<cmath>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<algorithm>
  7. #define ll long long
  8. #define re register
  9. #define il inline
  10. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  11. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  12. using namespace std;
  13. const int N=1e5+100;
  14. char s[N];
  15. int m,k,a[N];
  16. ll r,n,dp[5][15][N],sum[5][15][N];
  17. il ll gi()
  18. {
  19. re ll x=0,t=1;
  20. re char ch=getchar();
  21. while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  22. if(ch=='-') t=-1,ch=getchar();
  23. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  24. return x*t;
  25. }
  26. il void wri(re int x)
  27. {
  28. if(x<0) putchar('-'),x=-x;
  29. if(x>9) wri(x/10);
  30. putchar(x%10+'0');
  31. }
  32. int main()
  33. {
  34. n=gi();m=gi();r=gi();
  35. scanf("%s",s+1);
  36. fp(i,1,n)
  37. if(s[i]=='A') a[i]=1;else if(s[i]=='C') a[i]=2;else if(s[i]=='G') a[i]=3;else if(s[i]=='T') a[i]=4;
  38. if(a[n]) dp[a[n]][1][n]=1;
  39. else fp(i,1,4) dp[i][1][n]=1;
  40. fq(i,n-1,1)
  41. fp(j,1,4)
  42. if(!a[i]||a[i]==j)
  43. fp(k,1,m)
  44. fp(l,1,4)
  45. dp[j][k][i]+=dp[l][k-(j>l)][i+1];
  46. fp(i,1,4)
  47. fp(j,1,n)
  48. fp(k,1,m)
  49. sum[i][k][j]=sum[i][k-1][j]+dp[i][k][j];
  50. re int las=0;
  51. fp(i,1,n)
  52. if(a[i])
  53. {
  54. if(a[i]<las) --m;
  55. las=a[i];
  56. putchar(s[i]);
  57. }
  58. else
  59. {
  60. re int j;
  61. for(j=1;j<=4&&r>sum[j][m-(j<las)][i];j++) r-=sum[j][m-(j<las)][i];
  62. if(j==1) putchar('A');if(j==2) putchar('C');if(j==3) putchar('G');if(j==4) putchar('T');
  63. if(j<las) --m;
  64. las=j;
  65. }
  66. puts("");
  67. return 0;
  68. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注