bzoj4606 DNA
题意有点复杂,就自己去看吧。
题解
f[i][j][k]表示第i为,为-j范式,当前位为k的方案数,从后往前dp一遍。
然后再贪心的从前往后填数。但注意当前填的数已经是-cur范式,计算方案的时候要用k-cur来算。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define maxn 100020 7 8 typedef long long ll; 9 ll f[maxn][11][4],R; 10 int mp[200],a[maxn],ans[maxn]; 11 int n,k; 12 char ch[maxn],re[5]; 13 14 void init(){ 15 if ( a[n] == 5 ){ 16 for (int l = 0 ; l <= 3 ; l++){ 17 for (int i = 1 ; i <= k ; i++){ 18 f[n][i][l] = 1; 19 } 20 } 21 } 22 else{ 23 for (int i = 1 ; i <= k ; i++)f[n][i][a[n]] = 1; 24 } 25 for (int i = n - 1 ; i ; i--){ 26 if ( a[i] < 5 ){ 27 for (int j = 1 ; j <= k ; j++){ 28 for (int l = 0 ; l <= 3 ; l++){ 29 if ( a[i] >= l ) f[i][j][a[i]] += f[i + 1][j][l]; //如果有这种转移就不能在用f[i + 1][j - 1][l]在更新了。因为f[i + 1][j][l]已经包含了它的方案数,否则会算重 30 else f[i][j][a[i]] += f[i + 1][j - 1][l]; 31 } 32 } 33 } 34 else{ 35 for (int l = 0 ; l <= 3 ; l++){ 36 for (int j = 1 ; j <= k ; j++){ 37 for (int p = 0 ; p <= 3 ; p++){ 38 if ( l >= p ) f[i][j][l] += f[i + 1][j][p]; 39 else f[i][j][l] += f[i + 1][j - 1][p]; 40 } 41 } 42 } 43 } 44 } 45 /* for (int i = 1 ; i <= n ; i++) 46 for (int l = 0 ; l <= 3 ; l++) 47 for (int j = 1 ; j <= k ; j++){ 48 f[i][j][l] += f[i][j - 1][l]; 49 }*/ 50 } 51 void solve(){ 52 int cur = 1; 53 ans[0] = 5; 54 for (int i = 1 ; i <= n ; i++){ 55 if ( a[i] == 5 ){ 56 ll sum[4]; 57 for (int l = 0 ; l <= 3 ; l++){ 58 if ( ans[i - 1] < l ) sum[l] = f[i][k - cur][l]; 59 else sum[l] = f[i][k - cur + 1][l]; 60 } 61 for (int l = 3 ; l >= 0 && R > 0 ; l--){ 62 ans[i] = l , R -= sum[l]; 63 } 64 R += sum[ans[i]]; 65 if ( ans[i - 1] < ans[i] ) cur++; 66 } 67 else{ 68 ans[i] = a[i]; 69 if ( ans[i - 1] < ans[i] ) cur++; 70 } 71 } 72 for (int i = 1 ; i <= n ; i++) printf("%c",re[ans[i]]); 73 printf("\n"); 74 } 75 int main(){ 76 freopen("input.txt","r",stdin); 77 mp['A'] = 3 , mp['C'] = 2 , mp['G'] = 1 , mp['T'] = 0 , mp['N'] = 5; 78 re[3] = 'A' , re[2] = 'C' , re[1] = 'G' , re[0] = 'T'; 79 scanf("%d %d %lld",&n,&k,&R); 80 scanf("%s",ch + 1); 81 for (int i = 1 ; i <= n ; i++) a[i] = mp[(int)ch[i]]; 82 init(); 83 solve(); 84 }