HDU 4293 Groups
2012-09-16 18:55
381 查看
每个有效的(A,B),都能对应到一个group的区间[A+1,N-B]。把每个group看作一个节点,权值为这个group的player出现的次数(且不能超过区间长度)。若两个区间不冲突,从左边的区间向右边的连一条有向边。加上源点和终点(连上所有节点),求最长路。
更新dp解法,d[i]表示长度为i且包含以I结尾的区间时最大的人数。
//2012-09-16 18:56:27 Accepted 4293 156MS 2260K 1900 B G++ Aros #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int MAXN = 500+5, MAXM = 300000+5; const int INF = 0x3f3f3f3f; int N, a, b, A[MAXN], B[MAXN]; int n, s, t, mp[MAXN][MAXN]; int val[MAXN], d[MAXN]; int e, head[MAXN], next[MAXM], v[MAXM]; bool inq[MAXN]; queue<int> Q; void addedge(int x, int y) { v[e] = y; next[e] = head[x]; head[x] = e++; } void spfa() { for (int i = 1; i <= n; i++) d[i] = 0; memset(inq, 0, sizeof(inq)); Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for (int i = head[u]; i != -1; i = next[i]) if (d[v[i]] < d[u]+val[v[i]]) { d[v[i]] = d[u]+val[v[i]]; if (!inq[v[i]]) { Q.push(v[i]); inq[v[i]] = 1; } } } } int main() { while (scanf("%d", &N) != EOF) { e = 0; n = 0; memset(head, -1, sizeof(head)); memset(mp, 0, sizeof(mp)); memset(val, 0, sizeof(val)); for (int i = 1; i <= N; i++) { scanf("%d%d", &a, &b); if (a+b >= N) continue; int x = a+1, y = N-b, &m = mp[x][y]; if (!m) { m = ++n; A[m] = x; B[m] = y; } val[m] = min(B[m]-A[m]+1, val[m]+1); } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (B[i] < A[j]) addedge(i, j); s = n+1, t = n+2; val[s] = val[t] = 0; for (int i = 1; i <= n; i++) addedge(s, i), addedge(i, t); n += 2; spfa(); printf("%d\n", d[t]); } return 0; }
更新dp解法,d[i]表示长度为i且包含以I结尾的区间时最大的人数。
//2012-09-20 16:05:55 Accepted 4293 46MS 1224K 1178 B G++ Aros #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 500+5; const int INF = 0x3f3f3f3f; int N, a, b, A[MAXN], B[MAXN], r[MAXN]; int mp[MAXN][MAXN], num[MAXN], d[MAXN]; bool cmp(const int a, const int b) { return B[a] < B[b]; } int main() { while (scanf("%d", &N) != EOF) { memset(mp, 0, sizeof(mp)); memset(num, 0, sizeof(num)); memset(d, 0, sizeof(d)); int n = 0, ans = 0; for (int i = 1; i <= N; i++) { scanf("%d%d", &a, &b); if (a+b >= N) continue; int &m = mp[a+1][N-b]; if (!m) { m = ++n; A = a+1; B = N-b; r = n; } num[m] = min(num[m]+1, N-a-b); } sort(r+1, r+1+n, cmp); for (int i = 1; i <= n; i++) for (int j = 0; j < A[r[i]]; j++) d[B[r[i]]] = max(d[B[r[i]]], d[j]+num[r[i]]); for (int i = 1; i <= N; i++) ans = max(ans, d[i]); printf("%d\n", ans); } return 0; }
相关文章推荐
- HDU 4293 Groups
- HDU - 4293 Groups (DP)
- HDU 4293 Groups(区间DP)
- HDU 4293--Groups
- HDU 4293 Groups 区间覆盖 区间DP
- HDU 4293 Groups(区间dp)
- hdu 4293 Groups
- hdu 4293 Groups (2012 ACM/ICPC Asia Regional Chengdu Online)
- HDU 4293 Groups(12年成都网络赛-F题-DP)
- hdu 4293 Groups
- HDU 4293 Groups【区间dp】
- HDU 4293 Groups
- hdu 4293 Groups
- HDU 4293 Groups 拓扑排序
- hdu 4293 Groups
- hdu 4293 Groups
- HDU 4293 Groups
- HDU 4293 Groups (线性dp)
- Groups - HDU 4293 dp
- hdu 4293 Groups(动态规划)