UVALive 4031 Integer Transmission

来源:互联网 发布:刘涛直播网络瘫痪 编辑:程序博客网 时间:2024/05/19 13:08

题目大意:有n个比特,数字是 k ,现在要传输这n个比特,从左到右传输,每个比特传输有延迟,第i个比特到达的时间是 i ~ i+d,如果有多个同时到达,则顺序任意,问你能组成的数字的种数是多少,还有最大最小值是多少?

思路:最大最小值很好求,关键是那个种数,DP想了半天没想出来,没有好的思路,网上乱搜了两个代码,看了半天都没看懂,先贴上来吧,以后有时间再来搞。。

如果有哪位大神路过,希望能指点一下。。

代码1:

#include <stdio.h>#include <algorithm>#include <string.h>#include <iostream>using namespace std;const int maxn=100;int ob[maxn][2],pre[maxn],num[maxn][2];long long dp[maxn][maxn][maxn];int main(){int n,k,i,j,c,p,q;unsigned long long m;int s[100];int cas=0;while(scanf("%d",&n)!=EOF&&n!=0){cin>>k>>m;for(i=n;i>=1;i--){s[i]=m%2;m>>=1;}for(i=0;i<=n+1;i++)for(j=0;j<=n+1;j++)for(c=0;c<=n;c++)dp[i][j][c]=0;pre[0]=pre[1]=0;ob[0][0]=ob[0][1]=n+1;for(i=1;i<=n;i++){ob[i][s[i]]=n+1;ob[pre[s[i]]][s[i]]=i;pre[s[i]]=i;}ob[n+1][0]=ob[n+1][1]=n+1;dp[0][0][0]=1;for(i=0;i<=n+1;i++)for(j=0;j<=n+1;j++)for(c=0;c<n;c++)if(dp[i][j][c]){//printf("%d %d\n",ob[i][0],ob[j][1]);p=ob[i][0];q=ob[j][1];if(p<=n&&p<=q+k)dp[p][j][c+1]+=dp[i][j][c];if(q<=n&&q<=p+k)dp[i][q][c+1]+=dp[i][j][c];}long long ans=0;for(i=0;i<=n;i++)for(j=0;j<=n;j++)ans=max(ans,dp[i][j][n]);//for(i=1;i<n;i++)printf("%d ",s[i]);//printf("%d\n",s[n]);cas++;printf("Case %d: ",cas);cout<<ans;for(i=1;i<=n+k;i++)num[i][0]=num[i][1]=0;for(i=1;i<=n;i++)if(s[i]==0)num[i][0]++;else num[i+k][1]++;m=0;for(i=1;i<=n+k;i++){//printf("%d %d  ",num[i][0],num[i][1]);for(j=1;j<=num[i][0];j++)m=(m<<1);for(j=1;j<=num[i][1];j++)m=(m<<1)|1;}//printf("\n");cout<<" "<<m;for(i=1;i<=n+k;i++)num[i][0]=num[i][1]=0;for(i=1;i<=n;i++)if(s[i]==1)num[i][1]++;else num[i+k][0]++;m=0;for(i=1;i<=n+k;i++){for(j=1;j<=num[i][1];j++)m=(m<<1)|1;for(j=1;j<=num[i][0];j++)m=(m<<1);}cout<<" "<<m<<endl;}}


代码2:

#include <iostream>#include <cstring>#include <algorithm>#include <cmath>using namespace std;unsigned __int64 opt[65][65];int pos[2][100];int zeros[100];unsigned __int64 x;int len, d;inline void init(){memset(pos, 0, sizeof(pos));memset(zeros, 0, sizeof(zeros));unsigned __int64 t = x;for(int i = 0; i < len; i++){if(x % 2) pos[1][pos[1][0]++ + 1] = i;else pos[0][pos[0][0]++ + 1] = i, zeros[i]++;x /= 2;}x = t;for(int i = 1; i < len; i++) zeros[i] += zeros[i - 1];}unsigned __int64 solve(){memset(opt, 0, sizeof(opt));opt[0][0] = 1;for(int i = 0; i < len; i++)for(int j = 0; j <= pos[0][0]; j++){int tmp = i - j + 1;if(j < pos[0][0] && abs(i - pos[0][j + 1]) <= d) opt[i + 1][j + 1] += opt[i][j];if(i - j < pos[1][0] && abs(i - pos[1][tmp]) <= d && zeros[min(pos[1][tmp] + d, len - 1)] >= j && zeros[pos[1][tmp] - d - 1 < 0 ? 99 : pos[1][tmp] - d - 1] <= j) opt[i + 1][j] += opt[i][j];}return opt[len][pos[0][0]];}unsigned __int64 max_min(int v){int tmp[2][200];memset(tmp, 0, sizeof(tmp));unsigned __int64 tx = x, t = 0;for(int i = 0; i < len; i++){t *= 2;if(x % 2) t++;x /= 2;}for(int i = 0; i < len; i++, t /= 2)if(t % 2 == v) tmp[v][i + d]++;else tmp[!v][i]++;x = tx;unsigned __int64 res = 0;for(int i = 0; i < 200; i++){while(tmp[!v][i]--) { res *= 2; res += !v; }while(tmp[v][i]--) { res *= 2; res += v; }}return res;}int main(){int nc = 1;while(scanf("%d", &len)){if(!len) break;cin >> d >> x;init();unsigned __int64 x1 = max_min(1), x0 = max_min(0);cout << "Case " << nc++ << ": " << solve() << " " << x1 << " " << x0 << endl;}return 0;}



原创粉丝点击