SDUT 2021 Autumn Team Contest 36th G - Alice’s Stamps(补)
队友做出的这个题,赛后补的=、=
G - Alice’s Stamps (一般DP)
题目大意 :给你m个区间,选k个,求k个区间并集
1≤T≤100
1≤K≤M
1≤N,M≤2000
1≤Li≤ Ri ≤N
输出 :满足题意的最大的区间并
分析:
纯看数据范围很像是一般的背包dp,但是和常规背包不同,更像是一般的线性dp。同时一般的背包思维也不好想这个题。但我们用线性思维,先找出当前点在所有包含区间中的最左边界,(队友用当前点的最右边界写的也可过)
然后我们dp[i][j]表示为从左到j的区间内选i个区间的最大答案.
状态取 max.
(b[i]就是当前点的最小左区间在哪)然后能得dp方程 :
dp[i][j + 1] = max(max(dp[i][j + 1], dp[i][j]), dp[i - 1][b[j]] + j - b[j] + 1);
C++代码
/*made in dirt & sand */
#include <bits/stdc++.h>
#include <deque>
#define bug(a) cout << a << endl
#define mem(a, b) memset(a, b, sizeof a)
#define bug2(a, b) cout << a << ' ' << b << endl
#define bug3(a, b, c) cout << a << ' ' << b << ' ' << c << endl
#define lowbit(x) (x & -x)
#define pb push_back
#define int long long
#define x first
#define y second
#define pii pair<int, int>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 1e5 + 10, M = 1e7 + 10;
const int inf = 1e-6;
int i, j, k, n, m, l, x, y, t, ge, hao, ans[N], b[N], d[N];
vector<int> mp[N];
bool p[N];
struct ss
{
int x, y;
} a[N];
int dp[2010][2010];
bool cmp(ss x, ss y)
{
return x.x < y.x;
}
signed main()
{
// freopen("black.in","r",stdin);
std::ios::sync_with_stdio(false);
cin.tie(0);
int ans = 0;
int T;
cin >> T;
for (int ii = 1; ii <= T; ii++)
{
cin >> n >> m >> k;
for (i = 1; i <= n; i++)
b[i] = n + 10;
for (i = 0; i < m; i++)
{
cin >> a[i].x >> a[i].y;
}
sort(a, a + m, cmp);
int l = 1;
for (i = 0; i < m; i++)
{
for (; l <= a[i].y; l++)
{
b[l] = a[i].x;
}
}
for (j = 1; j <= n; j++)
{
for (i = 1; i <= k; i++)
{
dp[i][j + 1] = max(max(dp[i][j + 1], dp[i][j]), dp[i - 1][b[j]] + j - b[j] + 1);
}
ans = dp[k][j+1];
}
for(int nn = 0 ; nn <= m + 10 ; nn ++ ){
for(int mm = 0 ; mm <= n+11 ; mm ++ ){
dp[nn][mm] = 0;
}
}
printf("Case #%d: %lld\n", ii, ans);
}
}
调Bug闲聊
一直改不对,一开始是dp数组没初始化,后来初始化没干净,都初始化了也没找到哪里错了,后来是dp数组放前面初始化了。放到后面就初始化干净的原因是,b数组初始化的有点问题导致引用到上一个状态的dp数组,而上一个状态的dp数组没有完全初始化。现在想起来能调出来是真的离谱。。。