题目:有两个指令序列,在执行时,能够执行随意指令序列的下一条指令。每条指令要一直执行到结束。
求两组指令执行结束后,每一个变量里面存储值的期望。
分析:dp,模拟。这道题算不上难题,只是算得上的麻烦题了。
设状态 T[ i ][ j ] 为程序1运行i条指令,程序2运行j条指令后的变量平均值。P1为程序1指令i的概率,
P2为程序2指令j的概率。则easy推出,T[ i ][ j ] = (T[ i-1 ][ j ]*P1+T[ i ][ j-1 ]*P2)/(P1+P2);
只是须要注意几点:
1.理解题意非常重要,这个题非常easy误解 。
假设觉得每种指令运行的情况是一样的话。就会求错方程:(设N[ i ][ j ]为状态T[ i ][ j ]数量)
P1 = N[ i-1 ][ j ]/N[ i ][ j ]。P2 = N[ i ][ j-1 ]/N[ i ][ j ]。
以下是POJ discuss 里得解释,看了这个就会明确了:
Exactly one execution of the sample input results in S=8。and the probability of that execution is
not 1/C(8,4)=1/70, but (1/2)^4=1/16,since the program automatically execute remaining operations.
It is true that there are 70 different executions, but not all of them have the same probability.
正确的概率计算为:(设N1为程序1指令总条数,N2为程序2指令总条数)
if(i == N1 && j == N2)P1 = P[ i-1 ][ j ] ,P2 = P[ i ][ j-1 ];
if(i < N1 && j == N2)P1 = P[ i-1 ][ j ] ,P2 = P[ i ][ j-1 ]/2;
if(i == N1 && j < N2) P1 = P[ i-1 ][ j ]/2,P2 = P[ i ][ j-1 ];
if(i < N1 && j < N2)P1 = P[ i-1 ][ j ]/2,P2 = P[ i ][ j-1 ]/2。
P[ i ][ j ] = P1 + P2。
2.实现起来有点麻烦,要是比赛,仅仅能无题可做时才会做吧,由于这类似个小型的编译器了。
说明:囧,把P[ i-1 ][ j ]当成P1。P[ i ][ j-1 ]当成P2,WA了N次。(2011-09-19 09:35)
/* zoj1022 2011-03-22 03:05:19 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) char Command[ 2 ][ 26 ][ 65 ]; struct asmmble { int Varible1; int Varible2; char Operator; }Asmmble[ 2 ][ 105 ]; int Read( char Command[][ 65 ] ) { int List = 0; char ch = 0; while ( 1 ) { int Count = 0; while ( ( ch = getchar() ) != ' ' ) { while ( ch == ' ' ) ch = getchar(); Command[ List ][ Count ++ ] = ch; } Command[ List ][ Count ] = '