P3575-[POI2014]DOO-Around the world【环形dp】
生活随笔
收集整理的這篇文章主要介紹了
P3575-[POI2014]DOO-Around the world【环形dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意:https://www.luogu.org/problemnew/show/P3575
題目大意
一個環,上面有若干個點,若干個詢問xxx。
表示上一個降落點和下一個降落點距離不能超過xxx,然后求至少要降落多少次(起點可以任意)
解題思路
首先明顯環形dpdpdp,然后斷環成鏈,復制一份放到后面,預處理距離前綴和數組sumsumsum。
然后考慮貪心設lastilast_ilasti?數組,定義dpidp_idpi?表示lasti~i(i>n)last_i\sim i(i>n)lasti?~i(i>n)這段范圍的降落次數,然后優先飛最遠。也就是jjj是iii的最前的降落地點。因為jjj滿足單調性,所以就可以O(n)O(n)O(n)的預處理出來(或者在dpdpdp的時候處理)。然后首先顯然
dpi=dpj+1dp_i=dp_j+1dpi?=dpj?+1
然后因為計算上了dpjdp_jdpj?,所以要從lastjlast_jlastj?開始也就是
lasti=lastjlast_i=last_jlasti?=lastj?
然后當i?lasti>=ni-last_i>=ni?lasti?>=n時就是答案了。
codecodecode
#include<cstdio> #include<algorithm> #define ll long long using namespace std; const ll N=2000100; ll n,t,imp; ll sum[N],dp[N],last[N]; void get_answer(ll l){if(l<imp){printf("NIE\n");return;}for(ll i=n+1,j=1;i<=2*n;i++){while(sum[i]-sum[j]>l) j++;dp[i]=dp[j]+1;last[i]=last[j];if(i-last[i]>=n){printf("%lld\n",dp[i]);return;}} } int main() {scanf("%lld%lld",&n,&t);for(ll i=1;i<=n;i++){last[i]=i;scanf("%lld",&sum[i]);imp=max(imp,sum[i]);sum[i+n]=sum[i];sum[i]+=sum[i-1];}for(ll i=n+1;i<=2*n;i++)sum[i]+=sum[i-1];for(ll i=1;i<=t;i++){ll l;scanf("%lld",&l);get_answer(l);} }總結
以上是生活随笔為你收集整理的P3575-[POI2014]DOO-Around the world【环形dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 除诺基亚与自有品牌外,HMD 有望推出来
- 下一篇: IAR为瑞萨RA8系列MCU开发提供全面