Uva-1228 Integer Transmission(贪心+DP)

185 篇文章 0 订阅
116 篇文章 0 订阅

题意:你要在一个仿真网络中传输一个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;  	
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值