UVA1228 整数传输 (贪心 思维 dp)

╰半橙微兮° 2021-12-14 06:07 409阅读 0赞

题意:紫书P300。

分析:紫书P300-301。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 64;
  4. int n, d, K[maxn];
  5. unsigned long long f[maxn+1][maxn+1];
  6. int zcnt = 0, ocnt = 0;
  7. int Z[maxn], O[maxn]; // z[i] is the i-th zero from left (0-based)
  8. // now we received i zeros and j ones. Can we receive another zero at the next time?
  9. bool can_receive_zero(int i, int j) {
  10. return i+1 <= zcnt && (j == ocnt || O[j]+d >= Z[i]);
  11. }
  12. bool can_receive_one(int i, int j) {
  13. return j+1 <= ocnt && (i == zcnt || Z[i]+d >= O[j]);
  14. }
  15. unsigned long long minv, maxv;
  16. void greedy() {
  17. minv = maxv = 0;
  18. int i = 0, j = 0;
  19. while(i < zcnt || j < ocnt) {
  20. if(can_receive_zero(i, j)) { i++; minv = minv * 2; }
  21. else { j++; minv = minv * 2 + 1; }
  22. }
  23. i = j = 0;
  24. while(i < zcnt || j < ocnt) {
  25. if(can_receive_one(i, j)) { j++; maxv = maxv * 2 + 1; }
  26. else { i++; maxv = maxv * 2; }
  27. }
  28. }
  29. void solve() {
  30. // compute Z and O
  31. ocnt = zcnt = 0;
  32. for(int i = 0; i < n; i++)
  33. if(K[i] == 1) O[ocnt++] = i;
  34. else Z[zcnt++] = i;
  35. // greedy to get minv, maxv
  36. greedy();
  37. // dp
  38. memset(f, 0, sizeof(f));
  39. f[0][0] = 1;
  40. for(int i = 0; i <= zcnt; i++)
  41. for(int j = 0; j <= ocnt; j++) {
  42. if(can_receive_zero(i, j)) f[i+1][j] += f[i][j];
  43. if(can_receive_one(i, j)) f[i][j+1] += f[i][j];
  44. }
  45. cout << f[zcnt][ocnt] << " " << minv << " " << maxv << "\n";
  46. }
  47. int main() {
  48. int kase = 0;
  49. unsigned long long k;
  50. while(cin >> n >> d >> k) {
  51. for(int i = 0; i < n; i++) {
  52. K[n-i-1] = k % 2; k /= 2;
  53. }
  54. cout << "Case " << ++kase << ": ";
  55. solve();
  56. }
  57. return 0;
  58. }

发表评论

表情:
评论列表 (有 0 条评论,409人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数位DP UVA - 11038

    数位DP,顾名思义,是在个位,十位,百位,千位…….这些数的数位上进行的DP,它其实就是一种暴力枚举+记忆化搜索。 数位DP一般用来解决要求找出某个区间内,满足要求的数有多

    相关 整数划分--DP

    5. [数的划分][Link 1] 问题描述   将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。   例如:n=7,k=3,下面三种分法被认为是相同

    相关 整数划分 dp

    蒜头君特别喜欢数学。今天,蒜头君突发奇想:如果想要把一个正整数 nn 分解成不多于 kk 个正整数相加的形式,那么一共有多少种分解的方式呢? 蒜头君觉得这个问题实在是太难了,

    相关 UVA 10003 区间DP

    题意: 有一根长度为l的木棍,木棍上面有m个切割点,每一次切割都要付出当前木棍长度的代价,问怎样切割有最小代价。 分析: 石子合并的逆过程。状态:设F(i,j)为区间(

    相关 uva10859 (树形dp)

    题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮。每盏灯将照亮以它为一个端点的所有边。在灯的总数最小的前提下,被两盏灯同时被照亮的边数应该尽量