Forever Young

LOJ #515. 「LibreOJ β Round #2」贪心只能过样例

思路

暴力

每次当前层由上一层可以得到的数转化过来,用滚动数组实现
实际上就是一个背包

正解

暴力的瓶颈就在于在由上一层转化到当前层时需要暴力转化
考虑用一个 \(\text{bitset}\),每次加一个数 \(x\) 就相当于直接左移 \(x\) 位,最后输出 \(\text{bitset}\)\(1\) 的个数即可

代码

正解

/*
  Author: Loceaner
*/
#include <bits/stdc++.h>
using namespace std;

const int A = 1e3 + 11;
const int B = 1e7 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;

inline int read() {
  char c = getchar();
  int x = 0, f = 1;
  for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
  for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
  return x * f;
}

bitset <1000011> f[2];
int n, a[A], b[A];

int main() {
  n = read();
  for (int i = 1; i <= n; i++)
    a[i] = read(), b[i] = read();
  f[0][0] = 1;
  int now = 0;
  for (int i = 1; i <= n; i++) {
    now ^= 1;
    f[now].reset();
    for (int j = a[i]; j <= b[i]; j++)
      f[now] |= f[now ^ 1] << (j * j);
  }
  cout << f[now].count() << '\n';
  return 0;
}

暴力

/*
  Author: Loceaner
*/
#include <bits/stdc++.h>
using namespace std;

const int A = 1e6 + 11;
const int B = 1e7 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;

inline int read() {
	char c = getchar();
	int x = 0, f = 1;
	for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
	for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
	return x * f;
}

int n, a[2][A];

int main() {
	n = read();
	a[0][0] = 1;
	int now = 0, maxn = 1;
  for (int i = 1; i <= n; i++) {
	  now ^= 1;
	  memset(a[now], 0, sizeof(a[now]));
	  int l = read(), r = read();
    for (int j = l; j <= r; j++) {
	    for (int k = 0; k <= maxn; k++)
        if (a[now ^ 1][k] == 1) 
          a[now][k + j * j] = 1, maxn = max(maxn, k + j * j);
    }
  }
  int ans = 0;
  for (int i = 1; i <= maxn; i++) if (a[now][i]) ans++;
  cout << ans << '\n';
	return 0;
}
posted @ 2020-09-02 21:04  Loceaner  阅读(169)  评论(0编辑  收藏  举报