前年pj沒去年難好吧
首先要發現這個答案是有單調性的。
這個很顯然了:氪金越多遊戲越容易玩,氪金越少越難。
然而也有界限:如果所有正數的和加起來還不夠需求,無解。
所以二分答案,考慮如何判定答案。
是人都知道要設乙個\(dp[i]\)表示跳前\(i\)個房子的最大分數。
50pts就很簡單的暴力轉移:
\[dp[i]=max(dp[j]+a[i]),j < i,lim_1
其實很大的暗示了:把\(a[i]\)拿出來就是:\(dp[i]=a[i]+max(dp[j])\)
單調佇列走一波,維護滑動視窗最大值!
不得不說這裡的單調佇列很難寫對。
我們弄乙個指標\(j\),當我們求\(dp[i]\)的時候就移動\(j\)到最近。
然後當我們詢問最大值的時候再考慮討論退役人員的彈出,得到最大值。
**:
#includeusing std::cin;
using std::cout;
using std::endl;
#define ll long long
const int maxn = 500005;
const int inf = 0x8f8f8f8f;
int a[maxn], dis[maxn];
int dp[maxn];
int n, d, k;
std::dequeq;// dan diao di jian
bool check(int g)
}*/while(j < i && dis[i] - dis[j] >= lim1)
j++;
}while(!q.empty() && dis[i] - dis[q.front()] > lim2) q.pop_front();
if(!q.empty()) dp[i] = dp[q.front()] + a[i];
}int ans = 0x8f8f8f8f;
for(int i = 1; i <= n; i++) ans = std::max(ans, dp[i]);// wrong here
return ans >= k;
}int main()
int left = 0, right = std::max(dis[n], d), ans = -1;
while(left <= right)
cout << ans << endl;
return 0;
}
P3957 跳房子 單調佇列,dp,二分
這就是之前普及組的第四題 有n個格仔,每個格仔有價值。機械人有固定的跳躍距離d,用k個金幣改進的話,就可以讓跳躍距離在d k到d k之間,不過至少要往前跳1個單位長度,每次都必須跳到格仔上。要求超過需要的價值求需要消耗的最少金幣。二分所需金幣數然後 dp,f i f i 表示跳到第i個格仔最大價值,...
滑動視窗 二分 P3957 跳房子
思路 dp i 表示到第 i 個格仔的最大得分,仔細思考後發現 f i 只能從他之前一段區間內的最大 f i 轉移過來,且隨著區域的後移不斷改變,滑動視窗維護再二分答案就好了。實現 滑動視窗的活動範圍 max d len 1 to d len 滑動視窗的移動 當最大值的位置超過了他能跳到的最遠距離,...
題解 P3957 跳房子
題目鏈結 題目大意 給定 n 個格仔離原點距離以及權值,初始單次移動距離只能為 d 你可以花費 g 枚金幣使得單次移動距離變為 max d g,1 d g 內任意整數,問獲得權值至少為 k 最少需要花費多少枚金幣 單調佇列 分析 顯而易見答案具有單調性,因為花費金幣越多機械人越靈活,花費金幣少的可行...