UVA 1228 Integer Transmission

来源:互联网 发布:vscode svn插件 编辑:程序博客网 时间:2024/06/05 09:01

这本来是道简单的DP题目的。。

但是拖拖拉拉做了很久 = =

该题题意是传输一个最大64位的二进制数,传输过程中每个0或1有 1 ~ d+1 秒的随机延迟。然后求接收方能获得的最大值与最小值,还有可能接收到的二进制数的种数。

这里分析一下,最大值和最小值只要贪心一下就可以得到了,比较容易(求最大值让1尽量考前,求最小值让0尽量靠前)。但是可能获得的二进制数的种数,这个需要用DP解决,差不多是这道题的重点了。

因为二进制的特殊性,要不就是1要不就是0,所以直接分成两类来观察就可以了。Dp[ i ][ j ]就代表第 i 个1前有 j 个0的方案种数,根据插入第 i+1 个1和第 i 个1之间的0的个数IN,可以更新出Dp[ i+1 ][ j+IN ] ;这里可能插入的0的个数需要根据最大延迟 d 来进行判断。

那么问题就都解决了~

#include <stdio.h>#include <string.h>typedef unsigned long long LL;const int MAXM = 110;const LL F = 1;int Num,Limit;LL Data,All;LL Min,Max;LL Dp[MAXM][MAXM];int Queue[MAXM];int Zero[MAXM];int One[MAXM];void Get_Edge(LL Type,LL &Ans){int Start=0,End=0,hav=Num-1;for(int i=Num-1;i>=0;i--){if(((Data>>i)&F)==Type){Ans|=Type<<hav;hav--;}else{Queue[End++]=i;}if((Start<End)&&(Queue[Start]==i+Limit)){Ans|=(Type^F)<<hav;Start++;hav--;}}while(hav>=0){Ans|=(Type^F)<<hav;hav--;}}void Pushup(int pos,int front){int next=pos+1,in=1;while(Zero[front+in]-One[next]>Limit){in++;}Dp[next][front+in-1]+=Dp[pos][front];while(One[next]-Zero[front+in]<=Limit){Dp[next][front+in]+=Dp[pos][front];in++;}}void Get_Way(){int one=1,zero=1;memset(Dp,0,sizeof(Dp));for(int i=Num-1;i>=0;i--){if((Data>>i)&F){One[one++]=i;}else{Zero[zero++]=i;}}Zero[zero]=-MAXM;if(one==1||zero==1){All=1;return;}Dp[0][0]=1;Pushup(0,0);for(int i=1;i<one-1;i++){for(int t=0;t<zero;t++){if(Dp[i][t]){Pushup(i,t);}}}All=0;for(int t=0;t<zero;t++){All+=Dp[one-1][t];}}int main(){int Case=1;while(scanf("%d",&Num),Num){scanf("%d %llu",&Limit,&Data);Min=Max=0;Get_Edge(0,Min);Get_Edge(1,Max);Get_Way();printf("Case %d: %llu %llu %llu\n",Case++,All,Min,Max);}}


有个郁闷的地方是,输入输出应该是%llu。。。。不是%lld(我会说我WA了好几次么)

(╯‵□′)╯︵┻━┻(╯‵□′)╯︵┻━┻(╯‵□′)╯︵┻━┻


0 0