HDU 2983 Integer Transmission
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2983
题意:将一个n位的数发送,每一位的发送时间为i,但是网络有延迟d,收到时顺序可能会变,求总共有多少种可能性,并且最小和最大分别是多少
最大和最小比较容易求,只需要贪心的将1和0前移或后移
求方案数时,1和1的位置互换了并不影响,所以只需要考虑0和1的相对位置
用dp[i][j]表示现在接收了i个0,j个1
如果下一个1可以放在下一个0后面,那么现在可以接收0,如果下一个0可以放在下一个1后面,则可以接收1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int N=70;
typedef unsigned long long ll;
int cnt0,cnt1,p0[N],p1[N],n,d;
ll k,dp[N][N];
vector<int> v[N];
void init()
{
cnt0=cnt1=0;
for(int i=n-1;i>=0;i--)
if (k>>i&1)
p1[++cnt1]=-i;
else p0[++cnt0]=-i;
}
ll solve()
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=0;i<=cnt0;i++)
for(int j=0;j<=cnt1;j++)
{
if (i<cnt0&&(j==cnt1||p1[j+1]+d>=p0[i+1]))
dp[i+1][j]+=dp[i][j];
if (j<cnt1&&(i==cnt0||p0[i+1]+d>=p1[j+1]))
dp[i][j+1]+=dp[i][j];
}
return dp[cnt0][cnt1];
}
ll findmin()
{
for(int i=0;i<n;i++)
v[i].clear();
for(int i=n-1;i>=0;i--)
if (k>>i&1)
v[max(0,i-d)].push_back(1);
else v[i].push_back(0);
ll ans=0;
for(int i=n-1;i>=0;i--)
{
sort(v[i].begin(),v[i].end());
for(int j=0;j<v[i].size();j++)
ans=ans*2+v[i][j];
}
return ans;
}
bool cmp(ll x,ll y)
{
return x>y;
}
ll findmax()
{
for(int i=0;i<n;i++)
v[i].clear();
for(int i=n-1;i>=0;i--)
if (k>>i&1)
v[i].push_back(1);
else v[max(0,i-d)].push_back(0);
ll ans=0;
for(int i=n-1;i>=0;i--)
{
sort(v[i].begin(),v[i].end(),cmp);
for(int j=0;j<v[i].size();j++)
ans=ans*2+v[i][j];
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
int ca=0;
while(cin>>n&&n)
{
cin>>d>>k;
init();
ca++;
cout<<"Case "<<ca<<": "<<solve()<<" "<<findmin()<<" "<<findmax()<<endl;
}
return 0;
}

浙公网安备 33010602011771号