题意:你要在一个仿真网络中传输一个n比特的非负整数k。各比特从左到右传输,第i个比特的发送时间个i。每个比特的网络延迟总是0~d之间的实数。若同时有多个比特到达,实际收到的顺序任意。求实际收到的整数有多少种,以及它们的最小值和最大值。
分析:最大值就是把所有的0都设置d延迟所有1设置0延迟,最小相反。对于一个数p现在我们想判断它能不能通过对k设置一定延迟来得到,很容易发现这个问题可以直接贪心,只要假设p中所有的0和1还是保持k中的顺序就能判断了,于是我们考虑设计这样一个状态f[i][j]表示当前用了前i个0前j个1所能表示的所有合法序列的方案数,对于一个状态(i,j)当前序列中最后一个收到的字符的到达时间一定是max(time[i],time[j]),然后我们考虑序列的下一个字符,要保证下一个字符能在d的时间能达到max(time[i],time[j]),若能那么就把当前状态f[i][j]传给下一个状态.
#include <bits/stdc++.h>
#define N 204
#define INF 2147483647
using namespace std;
typedef pair<int,int> pii;
vector <pii> List;
bool camp1(pii a,pii b)
{
if(a.first == b.first) return a.second < b.second;
else return a.first > b.first;
}
bool camp2(pii a,pii b)
{
if(a.first == b.first) return a.second > b.second;
else return a.first > b.first;
}
int T,n,d,cnt[2],f_num[100][2];
unsigned long long k,ans1,ans2,f[100][100];
int main()
{
while(cin>>n>>d>>k && n)
{
memset(f,0,sizeof(f));
cnt[0] = cnt[1] = 0;
bitset<64> bit(k);
for(int i = n-1;i >= 0;i--)
f_num[++cnt[bit[i]]][bit[i]] = n-i;
f[0][0] = 1;
for(int i = 0;i <= cnt[0];i++)
for(int j = 0;j <= cnt[1];j++)
{
if(i != cnt[0] && f_num[i+1][0] + d >= f_num[j][1]) f[i+1][j] += f[i][j];
if(j != cnt[1] && f_num[j+1][1] + d >= f_num[i][0]) f[i][j+1] += f[i][j];
}
cout<<"Case "<<++T<<": "<<f[cnt[0]][cnt[1]]<<" ";
List.clear(),ans1 = ans2 = 0;
for(int i = n-1;i >= 0;i--)
if(bit[i]) List.push_back(make_pair(max(0,i-d),1));
else List.push_back(make_pair(i,0));
sort(List.begin(),List.end(),camp1);X
for(pii v : List) ans1 = ans1*2 + v.second;
cout<<ans1<<" ";
List.clear();
for(int i = n-1;i >= 0;i--)
if(bit[i]) List.push_back(make_pair(i,1));
else List.push_back(make_pair(max(0,i-d),0));
sort(List.begin(),List.end(),camp2);
for(pii v : List) ans2 = ans2*2 + v.second;
cout<<ans2<<endl;
}
}