6045_開餐館
阿新 • • 發佈:2018-12-15
/* Name: 6045_開餐館 Copyright: Author: Date: 24-06-18 13:39 Description: 描述 北大資訊學院的同學小明畢業之後打算創業開餐館.現在共有n 個地點可供選擇。小明打算從中選擇合適的位置開設一些餐館。這 n 個地點排列在同一條直線上。我們用一個整數序列m1, m2, ... mn 來表示他們的相對位置。由於地段關係,開餐館的利潤會有所不同。我們用pi 表示在mi 處開餐館的利潤。為了避免自己的餐館的內部競爭,餐館之間的距離必須大於k。請你幫助小明選擇一個總利潤最大的方案。 輸入 標準的輸入包含若干組測試資料。輸入第一行是整數T (1 <= T <= 1000) ,表明有T組測試資料。緊接著有T組連續的測試。每組測試資料有3行, 第1行:地點總數 n (n < 100), 距離限制 k (k > 0 && k < 1000). 第2行:n 個地點的位置m1 , m2, ... mn ( 1000000 > mi > 0 且為整數,升序排列) 第3行:n 個地點的餐館利潤p1 , p2, ... pn ( 1000 > pi > 0 且為整數) 輸出 對於每組測試資料可能的最大利潤 樣例輸入 2 3 11 1 2 15 10 2 30 3 16 1 2 15 10 2 30 樣例輸出 40 30 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAX = 1000; long long A[MAX+1]; //各點位置座標 long long P[MAX+1]; //各點餐館利潤 long long B[MAX+1]; //給定n個點開餐館的最大利潤 long long DP(int n, int d); long long DP_2(int n, int d); //動態規劃:類似最長上升子序列演算法 int main() { int d, n, t; cin >> t; for (int i=0; i<t; i++) { cin >> n >> d; for (int j=1; j<=n; j++) { cin >> A[j]; } for (int j=1; j<=n; j++) { cin >> P[j]; } memset(B, 0, sizeof(B)); cout << DP(n, d) << endl; } return 0; } long long DP(int n, int d) //動態規劃:類似最長上升子序列演算法 { B[1] = P[1]; //只在位置1開餐館 for (int i=2; i<=n; i++) { B[i] = max(B[i-1], P[i]); //比較不在位置i開餐館和只在位置i開餐館的大小 for (int j=i-1; j>0; j--)//尋求利潤最大的開餐館方法 { if (A[i] - A[j] > d && B[i] < B[j]+P[i])//找到第一個滿足條件的就可以跳出迴圈了 { B[i] = B[j]+P[i]; break; } } } return B[n]; } long long DP_2(int n, int d) //動態規劃:類似最長上升子序列演算法 { for (int i=1; i<=n; i++) { int j = i - 1; while (j>0 && A[i]-A[j]<=d)//找到第一個滿足條件的就可以跳出迴圈了 j--; B[i] = max(B[i-1], B[j]+P[i]); } return B[n]; }