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;
}

  

原文地址:https://www.cnblogs.com/bk-201/p/7473557.html