【HDU - 3440】House Man(差分约束)
題干:
In Fuzhou, there is a crazy super man. He can’t fly, but he could jump from housetop to housetop. Today he plans to use N houses to hone his house hopping skills. He will start at the shortest house and make N-1 jumps, with each jump taking him to a taller house than the one he is jumping from. When finished, he will have been on every house exactly once, traversing them in increasing order of height, and ending up on the tallest house.?
The man can travel for at most a certain horizontal distance D in a single jump. To make this as much fun as possible, the crazy man want to maximize the distance between the positions of the shortest house and the tallest house.?
The crazy super man have an ability—move houses. So he is going to move the houses subject to the following constraints:?
1. All houses are to be moved along a one-dimensional path.?
2. Houses must be moved at integer locations along the path, with no two houses at the same location.?
3. Houses must be arranged so their moved ordering from left to right is the same as their ordering in the input. They must NOT be sorted by height, or reordered in any way. They must be kept in their stated order.?
4. The super man can only jump so far, so every house must be moved close enough to the next taller house. Specifically, they must be no further than D apart on the ground (the difference in their heights doesn't matter).?
Given N houses, in a specified order, each with a distinct integer height, help the super man figure out the maximum possible distance they can put between the shortest house and the tallest house, and be able to use the houses for training.?
Input
In the first line there is an integer T, indicates the number of test cases.(T<=500)
Each test case begins with a line containing two integers N (1 ≤ N ≤ 1000) and D (1 ≤ D ≤1000000). The next line contains N integer, giving the heights of the N houses, in the order that they should be moved. Within a test case, all heights will be unique.?
Output
For each test case , output “Case %d: “first where d is the case number counted from one, then output a single integer representing the maximum distance between the shortest and tallest house, subject to the constraints above, or -1 if it is impossible to lay out the houses. Do not print any blank lines between answers.
Sample Input
3 4 4 20 30 10 40 5 6 20 34 54 10 15 4 2 10 20 16 13Sample Output
Case 1: 3 Case 2: 3 Case 3: -1題目大意:
有N個在一條直線上的房子, 每個房子有著不同的高度, 一個超人可以將這些房子左右移動 但不能改變房子之間的相對位置(只能把房子之間的距離拉開).?
現(xiàn)在超人要從最矮的房子跳到剛好比他高的房子上面, 且每次跳的房子都要比當(dāng)前房子要高.他要跳N-1次。?
那么最后超人肯定會跳到最高的房子上面, 現(xiàn)在給出超人一次能夠跳的最遠距離D, 問: 如何擺放這些房子, 使得超人能夠經(jīng)過所有的房子跳到最高的房子, 又要使最矮的房子和最高的房子 之間的距離最遠?
第一行一個整數(shù)T,表示數(shù)據(jù)組數(shù),T≤500。?
每組測試數(shù)據(jù),第一行兩個整數(shù)N和D?
接下來一行N個,表示從左到右每個房子的依次高度。
求最矮的和最高的可以到達的最遠距離。-1表示不可行。
解題報告:
? 直接差分約束建圖,求最大差,建A-B<=C的形式跑最短路就行了。
設(shè)s[i]代表第i個的相對位置,初始化s[st]=0。
滿足s[i] - s[i-1] >= 1 和 相鄰高度的s[]的差<=d這兩個條件即可。注意連邊的時候要下標(biāo)小的向大的連,而不是高度低的向高的連,因為你這里s[]數(shù)組代表的就是所在的位置,跟高度沒啥關(guān)系,高度就是確認連邊的兩個點的。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2000 + 5; const int INF = 0x3f3f3f3f; int n,D; struct Node {int id,h;bool operator<(const Node & b) const {return h < b.h;} } W[MAX]; int tot,head[MAX]; struct Edge {int v,ne,w; } e[MAX<<4];//應(yīng)該<<1就夠了? void add(int u,int v,int w) {e[++tot].v = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot; } int vis[MAX],dis[MAX],cnt[MAX]; int spfa(int st,int ed) {for(int i = 1; i<=n; i++) dis[i]=INF,vis[i]=cnt[i]=0;queue<int> q;q.push(st);vis[st]=1,dis[st]=0;while(q.size()) {int cur = q.front();q.pop();vis[cur] = 0;for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(dis[v] > dis[cur] + e[i].w) {dis[v] = dis[cur] + e[i].w;if(vis[v] == 0) {vis[v] = 1;cnt[v]++;if(cnt[v] > n) return -1;q.push(v);}}}}return dis[ed]; } int main() {int t,iCase=0;cin>>t;while(t--) {scanf("%d%d",&n,&D);tot=0;memset(head,-1,sizeof head);for(int i = 1; i<=n; i++) scanf("%d",&W[i].h),W[i].id = i;for(int i = 2; i<=n; i++) add(i,i-1,-1);sort(W+1,W+n+1);for(int x,y,i = 2; i<=n; i++) x=min(W[i-1].id,W[i].id),y=max(W[i-1].id,W[i].id),add(x,y,D);int x = min(W[1].id,W[n].id),y = max(W[1].id,W[n].id);int ans = spfa(x,y);printf("Case %d: %d\n",++iCase,ans);}return 0 ; }?
總結(jié)
以上是生活随笔為你收集整理的【HDU - 3440】House Man(差分约束)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【北航oj】(线段树取模运算)
- 下一篇: 让居民的储蓄搬家,向投资转化?现在的资本