日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JZOJ 3943. 【GDOI2015模拟11.29】环游世界

發布時間:2025/3/15 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 3943. 【GDOI2015模拟11.29】环游世界 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

ZTY 想要環游世界!他會駕駛一架飛機沿著赤道順時針飛行一周。現在他手頭有 S 架飛
機,每架飛機的油箱都有自己的容量限制di,表示在飛機的油箱裝滿的情況下,最遠可以飛
行多遠。赤道上有 n 座城市,相鄰兩座城市間有一定的距離。ZTY 有很多錢,所以你可以不
用考慮加油的問題,只需要認為降落到每座城市都可以把飛機的油箱加滿。
ZTY 想要盡快完成環游世界的目標,所以他想要飛機降落的次數盡量少。那么 ZTY 就想
要問你:對每架飛機,最少降落多少次才可以完成環游世界的任務?注意:ZTY 可以選擇任
意一個城市作為他的起點。另外,最后回到起點也需要算一次降落。

Input

第一行兩個整數,表示 n 與 s。
接下來一行 n 個整數,第 i 個整數表示第 i 個城市與第 i+1 個城市間的距離(第 n 個整數表
示第 n 個城市與第 1 個城市間的距離)。
接下來 s 個整數,第 i 個整數表示第 i 架飛機的容量限制di。

Output

對 s 架飛機每架飛機輸出一行。如果 ZTY 使用這架飛機不可能完成環游世界的目標,輸出
“NO”。否則輸出 ZTY 最少需要降落多少次。

Sample Input

樣例 1:

6 4
2 2 1 3 3 1
3 2 4 11

樣例 2:

8 3
2 2 2 2 2 2 2 2
1 16 2

Sample Output

樣例 1:

4
NO
3
2

樣例 2:

NO
1
8

Data Constraint

對 30%的數據 n 不超過 1000。
對 50%的數據 n 不超過 100000。
對另 10%的數據 s 不超過 5。
對 100%的數據 n 不超過 1000000,s 不超過 100。赤道長度(所有距離和)不超過109。所
有輸入小于231。

Hint

樣例 1 解釋:
對第一架飛機,可以按 6->2->4->5->6 的順序來飛行。
對第二架飛機,顯然它不能越過 4 與 5 之間 3 的距離。

Solution

  • 用一個數組 g[i] 表示當前的最優降落點集合。

  • 那么先以 1 為起始點,往后處理出 g[i](貪心地取),

  • 可以用前綴和來快速地算。

  • 之后再更改起始點 i,范圍為 1  g[1] ,因為之后的話就不必要了,相當于在前面先取。

  • 暴力更新當前的 g[i] ,由于點只會右移,由單調性知其均攤復雜度為 O(1)

  • 則遍歷到 i+n 后查看 g[i] 中的元素個數是否優于答案即可。

  • 總時間復雜度 O(S?N)

Code

#include<cstdio> #include<cctype> using namespace std; const int N=2e6+5; int mx,tot; int a[N],f[N],g[N]; inline int read() {int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } inline int min(int x,int y) {return x<y?x:y; } int main() {int n=read(),s=read();for(int i=1;i<=n;i++){a[i]=a[i+n]=read();if(a[i]>mx) mx=a[i];}for(int i=1;i<=n<<1;i++) f[i]=f[i-1]+a[i];while(s--){int d=read();if(d<mx){puts("NO");continue;}g[0]=tot=0;for(int i=1;i<=n;i++)if(f[i]-f[g[tot]]>d) g[++tot]=i-1;g[++tot]=n;int ans=tot;for(int i=1,q=g[1];i<=q;i++){g[0]++;bool pd=true;for(int j=1;j<=tot;j++){if(g[j]<=g[j-1]) g[j]=g[j-1]+1;while(g[j]<i+n && f[g[j]+1]-f[g[j-1]]<=d) g[j]++;if(g[j]==i+n){ans=min(ans,j);pd=false;break;}}if(pd) g[++tot]=i+n;}printf("%d\n",ans);}return 0; }

總結

以上是生活随笔為你收集整理的JZOJ 3943. 【GDOI2015模拟11.29】环游世界的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。