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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Noip2017 跳房子——普及组

發(fā)布時(shí)間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Noip2017 跳房子——普及组 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原題地址(點(diǎn)我)

題目描述

跳房子,也叫跳飛機(jī),是一種世界性的兒童游戲,也是中國民間傳統(tǒng)的體育游戲之一。

跳房子的游戲規(guī)則如下:

在地面上確定一個(gè)起點(diǎn),然后在起點(diǎn)右側(cè)畫 n 個(gè)格子,這些格子都在同一條直線上。每個(gè)格子內(nèi)有一個(gè)數(shù)字( 整數(shù)),表示到達(dá)這個(gè)格子能得到的分?jǐn)?shù)。玩家第一次從起點(diǎn)開始向右跳, 跳到起點(diǎn)右側(cè)的一個(gè)格子內(nèi)。第二次再從當(dāng)前位置繼續(xù)向右跳,依此類推。規(guī)則規(guī)定:

玩家每次都必須跳到當(dāng)前位置右側(cè)的一個(gè)格子內(nèi)。玩家可以在任意時(shí)刻結(jié)束游戲,獲得的分?jǐn)?shù)為曾經(jīng)到達(dá)過的格子中的數(shù)字之和。

現(xiàn)在小 R 研發(fā)了一款彈跳機(jī)器人來參加這個(gè)游戲。但是這個(gè)機(jī)器人有一個(gè)非常嚴(yán)重的缺陷,它每次向右彈跳的距離只能為固定的 d。小 R 希望改進(jìn)他的機(jī)器人,如果他花 g 個(gè)金幣改進(jìn)他的機(jī)器人,那么他的機(jī)器人靈活性就能增加 g, 但是需要注意的是,每次彈跳的距離至少為 1。 具體而言, 當(dāng)g < d時(shí), 他的機(jī)器人每次可以選擇向右彈跳的距離為 d-g, d-g+1,d-g+2, …, d+g-2, d+g-1, d+g; 否則( 當(dāng)g ≥ d時(shí)),他的機(jī)器人每次可以選擇向右彈跳的距離為 1, 2, 3, …, d+g-2, d+g-1, d+g。

現(xiàn)在小 R 希望獲得至少 k 分,請問他至少要花多少金幣來改造他的機(jī)器人。

輸入輸出格式

輸入格式:

?

第一行三個(gè)正整數(shù) n, d, k, 分別表示格子的數(shù)目, 改進(jìn)前機(jī)器人彈跳的固定距離, 以及希望至少獲得的分?jǐn)?shù)。 相鄰兩個(gè)數(shù)之間用一個(gè)空格隔開。

接下來 n 行,每行兩個(gè)正整數(shù)xi, si,分別表示起點(diǎn)到第i個(gè)格子的距離以及第i個(gè)格子的分?jǐn)?shù)。 兩個(gè)數(shù)之間用一個(gè)空格隔開。 保證x_i按遞增順序輸入。

?

輸出格式:

?

共一行,一個(gè)整數(shù),表示至少要花多少金幣來改造他的機(jī)器人。若無論如何他都無法獲得至少 k 分,輸出-1。

?

輸入輸出樣例

Sample Input1

7 4 10
2 6
5 -3
10 3
11 -3
13 1
17 6
20 2

Sample Output1

2

Sample Input2

7 4 20
2 6
5 -3
10 3
11 -3
13 1
17 6
20 2

Sample Output2

-1

說明

輸入輸出樣例 1 說明

花費(fèi) 2 個(gè)金幣改進(jìn)后, 小 R 的機(jī)器人依次選擇的向右彈跳的距離分別為 2, 3, 5, 3, 4,3, 先后到達(dá)的位置分別為 2, 5, 10, 13, 17, 20, 對應(yīng) 1, 2, 3, 5, 6, 7 這 6 個(gè)格子。這些格子中的數(shù)字之和 15 即為小 R 獲得的分?jǐn)?shù)。

輸入輸出樣例 2 說明

由于樣例中 7 個(gè)格子組合的最大可能數(shù)字之和只有 18 ,無論如何都無法獲得 20 分

數(shù)據(jù)規(guī)模與約定

本題共 10 組測試數(shù)據(jù),每組數(shù)據(jù) 10 分。

對于全部的數(shù)據(jù)滿足1 ≤ n ≤ 500000, 1 ≤ d ≤2000, 1 ≤ x_i, k ≤ 109, |si| < 105。 對于第 1, 2 組測試數(shù)據(jù), n ≤ 10;

對于第 3, 4, 5 組測試數(shù)據(jù), n ≤ 500

對于第 6, 7, 8 組測試數(shù)據(jù), d = 1


這道題的思想是DP+單調(diào)隊(duì)列維護(hù)+二分找答案
我寫的代碼↓,有點(diǎn)惡心
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <climits>
 5 #define Ll long long
 6 using namespace std;
 7 const int inf=INT_MAX;
 8 Ll f[500001];
 9 int s[500001];
10 int g[500001],w[500001];
11 int head,ll,tail;
12 int n,d,k;
13 int l,r;
14 bool check(int l,int r)
15 {
16     for (int i=1;i<=n;i++)
17         f[i]=-inf;
18     head=1,tail=0,ll=0;
19     for (int i=1;i<=n;i++)
20     {
21         while(ll<i && g[i]-g[ll]>=l)
22         {
23             s[++tail]=ll;
24             ll++;
25             while(f[s[tail]]>f[s[tail-1]] && tail>head)
26             {
27                 s[tail-1]=s[tail];
28                 tail--;
29             }
30         }
31         while(head<=tail && g[i]-g[s[head]]>r)
32             head++;
33         if(head>tail)
34             continue;
35         f[i]=f[s[head]]+w[i];
36         if(f[i]>=k) 
37             return 1;
38     }
39     return 0;
40 }
41 int main()
42 {
43     //freopen("jump.in","r",stdin);
44     //freopen("jump.out","w",stdout);
45     scanf("%d%d%d",&n,&d,&k); 
46     for(int i=1;i<=n;i++)
47     {
48         scanf("%d",&g[i]);
49         scanf("%d",&w[i]);
50     }
51     l=1,r=g[n]+1;
52     while(l<r)
53     {
54         int mid=(l+r)>>1;
55         if(check(max(d-mid,1),d+mid))
56             r=mid;
57         else
58             l=mid+1;
59     }
60     if(l==g[n]+1)
61         l=-1;
62     printf("%d\n",l);
63     return 0;
64 }
jump1
 

?非惡心代碼↓

?

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <climits>
 5 #define ll long long
 6 using namespace std;
 7 const int inf=INT_MAX;
 8 int x[500001],a[500001],q[500001];
 9 ll f[500001];
10 int n,d,k;
11 int l,r,mid;
12 int ans;
13 int check(int z)
14 {
15       int head=1,tail=1,tmp;
16       q[1]=0,f[0]=0;
17       for (int i=1;i<=n;i++)
18           f[i]=-inf;
19       tmp=0;
20       for (int i=1;i<=n;i++) 
21     {
22           while(x[i]-x[tmp]>d+z && tmp<=i)
23               tmp++;
24           while(tmp<i && x[i]-x[tmp]>=d-z && x[i]-x[tmp]<=d+z)
25         {
26               while(f[tmp]>f[q[tail]] && head<=tail)
27                   tail--;
28               tail++;
29               q[tail]=tmp;
30               tmp++;
31         }
32           while(x[i]-x[q[head]]>d+z && head<=tail)
33               head++;
34           if (head<=tail && x[i]-x[q[head]]>=d-z && x[i]-x[q[head]]<=d+z)
35               f[i]=f[q[head]]+a[i];
36           if (f[i]>=k)
37               return 1;
38     }
39       return 0;
40 }
41 int main()
42 {
43     //freopen("jump.in","r",stdin);
44     //freopen("jump.out","w",stdout);
45       scanf("%d%d%d",&n,&d,&k);
46       for (int i=1;i<=n;i++)
47           scanf("%d%d",&x[i],&a[i]);
48       l=0,r=x[n];
49       ans=-1;
50       while(l<=r)
51     {
52           mid=(l+r)>>1;
53           if (check(mid))
54         {
55             ans=mid;
56             r=mid-1;
57         }
58         else
59             l=mid+1;
60     }
61       printf("%d\n",ans);
62       return 0;
63 }
jump2

?

?另外安利OLM大神的題解

?地址:http://blog.csdn.net/ac_is_fun/article/details/78565575

?%%%OLM大神

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/LHR-HY/p/7857401.html

總結(jié)

以上是生活随笔為你收集整理的Noip2017 跳房子——普及组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。