zoj 1022 - Parallel Expectations
题目:有两个指令序列,在执行时,能够执行随意指令序列的下一条指令。每条指令要一直执行到结束。
求两组指令执行结束后,每一个变量里面存储值的期望。
分析: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() ) != '\n' ) {
while ( ch == ' ' ) ch = getchar();
Command[ List ][ Count ++ ] = ch;
}
Command[ List ][ Count ] = '\0';
if ( !strcmp( Command[ List ], "END" ) ) break;
if ( strcmp( Command[ List ], "" ) ) ++ List;
}
return List;
} struct word {
int Start;
int End;
}Word[ 3 ]; struct varible {
char Name[ 21 ];
int Length;
double Value;
bool IsConst;
}Varible[ 155 ]; int Search( int& Number, char* String, int number )
{
for ( int i = 4 ; i < Number ; ++ i )
if ( Varible[ i ].Length == number && !strcmp( Varible[ i ].Name, String ) )
return i;
strcpy( Varible[ Number ].Name, String );
Varible[ Number ].Length = number;
Varible[ Number ].IsConst = false;
Varible[ Number ].Value = 0.0;
return Number ++;
} char Change( char ch )
{
if ( ch >= 'a' && ch <= 'z' )
return ch - 'a' + 'A';
return ch;
} int searchVarible( char* Command, word Word, int& Number )
{
int count = 0;
char String[ 21 ];
if ( Command[ Word.Start ] >= '0' && Command[ Word.Start ] <= '9' ) {
count = Command[ Word.Start ++ ]-'0';
while ( Word.Start <= Word.End ) {
count *= 10;
count += Command[ Word.Start ++ ]-'0';
}
strcpy( Varible[ Number ].Name, "0");
Varible[ Number ].Length = 1;
Varible[ Number ].IsConst = true;
Varible[ Number ].Value = count;
return Number ++;
}else {
int number = 0;
String[ number ++ ] = Change( Command[ Word.Start ++ ] );
while ( Word.Start <= Word.End )
String[ number ++ ] = Change( Command[ Word.Start ++ ] );
String[ number ] = '\0';
return Search( Number, String, number );
}
} void commbine( int m, int n, int v1, int v2 ,char o3 )
{
Asmmble[ m ][ n ].Varible1 = v1;
Asmmble[ m ][ n ].Varible2 = v2;
Asmmble[ m ][ n ].Operator = o3;
} void Operat( int n, int m, int XX, int YY, int ZZ, char O )
{
int R1 = 2*m+0;
int R2 = 2*m+1;
commbine( m, 4*n+1, R1, YY, ':' );
commbine( m, 4*n+2, R2, ZZ, ':' );
commbine( m, 4*n+3, R1, R2, O );
commbine( m, 4*n+4, XX, R1, ':' );
} int FindChar( char* p, char O )
{
int count = 0;
while ( p[ count ] ) {
if ( p[ count ] == O )
return count;
++ count;
}
return -1;
} int command( int machine, char Command[][ 65 ], int List, int Number )
{
for ( int i = 0 ; i < List ; ++ i ) {
int space1 = FindChar( Command[ i ], ':' );
int space2 = max( FindChar( Command[ i ], '+' ), FindChar( Command[ i ], '-' ) );
int space3 = strlen( Command[ i ] );
Word[ 0 ].Start = 0; Word[ 0 ].End = space1-1;
Word[ 1 ].Start = space1+2; Word[ 1 ].End = space2-1;
Word[ 2 ].Start = space2+1; Word[ 2 ].End = space3-1; int X = searchVarible( Command[ i ], Word[ 0 ], Number );
int Y = searchVarible( Command[ i ], Word[ 1 ], Number );
int Z = searchVarible( Command[ i ], Word[ 2 ], Number ); Operat( i, machine, X, Y, Z, Command[ i ][ space2 ] );
}
return Number;
} void calculate( double* Var, asmmble Asm )
{
switch( Asm.Operator ) {
case ':': Var[ Asm.Varible1 ] = Var[ Asm.Varible2 ];break;
case '+': Var[ Asm.Varible1 ] += Var[ Asm.Varible2 ];break;
case '-': Var[ Asm.Varible1 ] -= Var[ Asm.Varible2 ];break;
}
} int cmpstr( char* a, char* b, int n )
{
for ( int i = 0 ; i < n ; ++ i )
if ( a[ i ] != b[ i ] )
return a[ i ] - b[ i ];
return 0;
} int cmp( const void* a, const void* b )
{
struct varible* p = (struct varible*)a;
struct varible* q = (struct varible*)b;
if ( p->IsConst == q->IsConst ) {
int value = cmpstr( p->Name, q->Name, min( p->Length, q->Length ) );
if ( !value )
return p->Length - q->Length;
else return value;
}else return q->IsConst - p->IsConst;
} double M1[ 55 ],M2[ 55 ];
double P[ 105 ][ 105 ],P1,P2;
double T[ 101 ][ 101 ][ 35 ]; void dp( int number1, int number2, int count )
{
P[ 0 ][ 0 ] = 1.0; for ( int k = 0 ; k < count ; ++ k )
if ( Varible[ k ].IsConst )
T[ 0 ][ 0 ][ k ] = Varible[ k ].Value+0.0;
else
T[ 0 ][ 0 ][ k ] = 0.0; for ( int i = 1 ; i <= number1 ; ++ i ) {
P[ i ][ 0 ] = 0.5*P[ i-1 ][ 0 ];
for ( int k = 0 ; k < count ; ++ k )
T[ i ][ 0 ][ k ] = T[ i-1 ][ 0 ][ k ];
calculate( T[ i ][ 0 ], Asmmble[ 0 ][ i ] );
} for ( int j = 1 ; j <= number2 ; ++ j ) {
P[ 0 ][ j ] = 0.5*P[ 0 ][ j-1 ];
for ( int k = 0 ; k < count ; ++ k )
T[ 0 ][ j ][ k ] = T[ 0 ][ j-1 ][ k ];
calculate( T[ 0 ][ j ], Asmmble[ 1 ][ j ] );
} for ( int i = 1 ; i <= number1 ; ++ i )
for ( int j = 1 ; j <= number2 ; ++ j ) {
for ( int k = 0 ; k < count ; ++ k ) {
M1[ k ] = T[ i-1 ][ j ][ k ];
M2[ k ] = T[ i ][ j-1 ][ k ];
}
calculate( M1, Asmmble[ 0 ][ i ] );
calculate( M2, Asmmble[ 1 ][ j ] ); if ( i < number1 && j < number2 ) {
P1 = P[ i-1 ][ j ]/2;P2 = P[ i ][ j-1 ]/2;
}else if ( i < number1 ) {
P1 = P[ i-1 ][ j ]; P2 = P[ i ][ j-1 ]/2;
}else if ( j < number2 ) {
P1 = P[ i-1 ][ j ]/2;P2 = P[ i ][ j-1 ];
}else {
P1 = P[ i-1 ][ j ] ;P2 = P[ i ][ j-1 ];
}
P[ i ][ j ] = P1 + P2;
//用 P[ i-1 ][ j ],P[ i ][ j-1 ] 取代 P1,P2的值了。 。。 for ( int k = 0 ; k < count ; ++ k )
T[ i ][ j ][ k ] = (P1*M1[ k ]+P2*M2[ k ])/(P[ i ][ j ]);
} for ( int k = 0 ; k < count ; ++ k )
Varible[ k ].Value = T[ number1 ][ number2 ][ k ]; qsort( &Varible[ 4 ], count-4, sizeof( Varible[ 0 ] ), cmp ); int start = 4;
while ( Varible[ start ].IsConst ) ++ start;
for ( int i = start ; i < count ; ++ i )
printf("%.4lf\n",Varible[ i ].Value);
} void Initial( void )
{
for ( int k = 0 ; k < 4 ; ++ k ) {
Varible[ k ].IsConst = false;
Varible[ k ].Value = 0.0;
}
} int main()
{
int t,line1,line2,numb1,numb2;
while ( scanf("%d",&t) != EOF )
while ( t -- ) {
Initial(); line1 = Read( Command[ 0 ] );
line2 = Read( Command[ 1 ] ); numb1 = command( 0, Command[ 0 ], line1, 00004 );
numb2 = command( 1, Command[ 1 ], line2, numb1 ); dp( 4*line1, 4*line2, numb2 );
if ( t ) printf("\n");
}
return 0;
} /* 測试
//////////////////////////////////////////////
void test( int number1, int number2, int count )
{
int save[ 2 ];
save[ 0 ] = number1;
save[ 1 ] = number2;
for ( int machine = 0 ; machine <= 1 ; ++ machine ) {
printf("machine %d:\n__________________\n",machine+1);
for ( int k = 1 ; k <= save[ machine ] ; ++ k )
printf("%3s %3s %3s\n",deal1(Asmmble[ machine ][ k ].Operator, A1),
deal2(Asmmble[ machine ][ k ].Varible1, A2),
deal2(Asmmble[ machine ][ k ].Varible2, A3));
printf("\n");
}
} char* deal1( char Operator, char* Answer )
{
switch( Operator ) {
case ':': strcpy( Answer, "MOV" );break;
case '+': strcpy( Answer, "ADD" );break;
case '-': strcpy( Answer, "SUB" );break;
}
return Answer;
} char* deal2( int Value, char* Answer )
{
if ( Value < 4 ) {
Answer[ 0 ] = 'R';
Answer[ 1 ] = Value/2+'1';
Answer[ 2 ] = Value%2+'1';
Answer[ 3 ] = '\0';
}else if ( Varible[ Value ].IsConst ) {
Answer[ 0 ] = (int)Varible[ Value ].Value/100+'0';
Answer[ 1 ] = (int)Varible[ Value ].Value%100/10+'0';
Answer[ 2 ] = (int)Varible[ Value ].Value%10+'0';
Answer[ 3 ] = '\0';
}else
strcpy( Answer, Varible[ Value ].Name );
return Answer;
} char A1[ 20 ],A2[ 20 ],A3[ 20 ];
/////////////////////////////////////////////////////
*/
zoj 1022 - Parallel Expectations的更多相关文章
- 一位学长的ACM总结(感触颇深)
发信人: fennec (fennec), 信区: Algorithm 标 题: acm 总结 by fennec 发信站: 吉林大学牡丹园站 (Wed Dec 8 16:27:55 2004) AC ...
- POJ题目细究
acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP: 1011 NTA 简单题 1013 Great Equipment 简单题 102 ...
- 【转】POJ百道水题列表
以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...
- POJ题目排序的Java程序
POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...
- 别人整理的DP大全(转)
动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...
- dp题目列表
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- poj 动态规划题目列表及总结
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- [转] POJ DP问题
列表一:经典题目题号:容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1191,1208, 1276, 13 ...
- poj动态规划列表
[1]POJ 动态规划题目列表 容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276, 13 ...
随机推荐
- nyoj228 士兵杀敌(5)插线问线
士兵杀敌(五) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为0~M,每次有任务的时候,总会有一批编号连在一起人请战 ...
- Office 2013 Excel 打开文档很慢很慢的解决方法
这个问题查了很多案例,试了很多方法,但是只有下面这个方法有用! 这几天打开excel文档很慢很慢,双击之后好久没反应,过会儿它才慢慢冒出来,当时将就了,刚刚休息的时候想着查一下吧,不然很影响工作效率! ...
- 基于HTML5 Canvas粒子效果文字动画特效
之前我们分享过很多超酷的文字特效,其中也有利用HTML5和CSS3的.今天我们要来分享一款基于HTML5 Canvas的文字特效,输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的 ...
- elasticsearch介绍
elasticsearch是一个基于lucene所编写的分布式的搜索引擎,能够达到实时搜索,稳定高效. 我所了解的elasticsearch有下面这些特点 1 配置简单,对于初学者来说几乎是下载后零配 ...
- Qt5 can't find -LGL
一周前新建了一个有关Ubuntu QT5 的虚拟机开发环境,在官网上下载了一个完整的run包,然后编译的时候发现如下错误 can't find -LGL 解决方式: sudo apt-get inst ...
- u-boot中网口处理--硬件部分
1. 网口硬件方案: AT91SAM9G10 + DM9000CEP: DM9000CEP为MAC+PHY解决方案,与MCU链接通过8位或16位数据总线. 内部SRAM为16Kbyte. 2. DM ...
- datanode与namenode的通信
在分析DataNode时, 因为DataNode上保存的是数据块, 因此DataNode主要是对数据块进行操作. A. DataNode的主要工作流程1. 客户端和DataNode的通信: 客户端向D ...
- windows系统IIS服务安装
打开控制面板,win8可以使用快捷键win键+X打开列表 打开程序和功能 打开左上角启用或关闭windows功能 打开internet信息服务下拉单 按照下列图中进行对应项勾选 第一个 ...
- iOS边练边学--plist文件,懒加载,模型初使用--补充instancetype
一.什么是plist文件 1>将数据直接写在代码里面,不是一种合理的做法.如果数据经常修改,就要经常翻开对应的代码进行修改,造成代码扩展性低 2>因此,可以考虑将经常变得数据放在文件中进行 ...
- rufus/scheduler
之前先在initializers 文件夹下建立了一个task.rb ,rails服务启动的时候执行,本地没问题,可是服务器上启动了3个进程,会执行3遍,解决方法是 把task.rb 放到 script ...