Idea: DP [I] [now] [Mark] [Len] I indicates that the last 8 digits are stored in the current next time now, when Mark is set to 9th bits, it is set to 0, or 1 Len is set to the ninth bits, and there are several BITs equal to 9th bits. Reason for saving only the last 8 bits: If an operation is performed for only 200 times, the last 8 bits can be expressed. If the eighth bits of multiplication are known, the ninth bits and the forward length are known, so it can indicate all States.
The problem is that 10 1111 1111 at this time, after 1 is added, it will become 11 0000 0000 200. However, the result will be affected in this way. If all the subsequent operations are addition, only times, it is impossible for him to affect the previous 1, multiplication is equivalent to moving left without affecting. Therefore, the preceding 1 cannot be used as the answer.
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include <iostream>using namespace std;double d[210][260][2][260];int a[15];int main() { int x, k, p, h = 0; memset(d, 0, sizeof(d)); memset(a, 0, sizeof(a)); scanf("%d%d%d", &x, &k, &p); while (x) { a[h++] = x %2; x /= 2; } int now = 0; for (int i = 0; i < 8; ++i) if (a[i]) now += (1 << i); if (h < 9) { d[0][now][0][0] = 1; } else { int cnt = 1; for (int i = 9; i < h; ++i) { if (a[i] != a[i - 1]) break; cnt++; } d[0][now][a[8]][cnt] = 1; } for (int i = 0; i < k; ++i) { for (int j = 0; j <= 255; ++j) { for (int x = 0; x <= 250; ++x) { if (j != 255) { d[i + 1][j + 1][0][x] += d[i][j][0][x] * (100 - p) / 100.0; d[i + 1][j + 1][1][x] += d[i][j][1][x] * (100 - p) / 100.0; } else { d[i + 1][0][0][x] += d[i][j][1][x] * (100 - p) / 100.0; d[i + 1][0][1][1] += d[i][j][0][x] * (100 - p) / 100.0; } if (j & (1 << 7)) { d[i + 1][(j << 1) % 256][1][1] += d[i][j][0][x] * p / 100.0; d[i + 1][(j << 1) % 256][1][x + 1] += d[i][j][1][x] * p / 100.0; } else { d[i + 1][(j << 1) % 256][0][1] += d[i][j][1][x] * p / 100.0; d[i + 1][(j << 1) % 256][0][x + 1] += d[i][j][0][x] * p / 100.0; } } } } double sum=0; for(int i=1;i<255;++i) { for(int j=0;j<2;++j) for(int x=0;x<=250;++x) { int now=i; int cnt=0; while(now%2==0) { cnt++; now/=2; } sum+=d[k][i][j][x]*cnt; } } for(int x=0;x<=250;++x) sum+=d[k][0][1][x]*8; for(int x=0;x<=250;++x) sum+=d[k][0][0][x]*(x+8); printf("%.10lf\n",sum); return 0;}
View code