普及組的題。。。
我不會。。。 題目
思路很簡單,就是二分答案+dp+單調佇列(線段樹也可以),但是要注意細節,乙個細節錯了,一半分數就沒了。
引用洛谷上某大佬的一段話:
發現答案的可行區間是單調的,所以二分答案,容易推出f[i]表示到達第i個格仔的最大值,列舉上一步跳了多少來轉移線段樹:然後仔細觀察可以發現對於乙個狀態,如果有比他後面的狀態比他答案大的話,顯然不會優..於是可以單調佇列進行優化
但是考慮對於乙個點,他前面和他距離小於d-g的點是轉移不到的,如果直接得出某個f[i]後就將他放進佇列顯然是錯誤的
考慮維護乙個指標,表示當前最前面的乙個沒有加入單調佇列的元素,當且僅當當前節點和他相差》=d-g的時候就讓這個元素進隊
顯然這個指標也是單調的,也可以得出每個點在一次check中最多被指標指向一次;
處理完之後在一遍pop將所有和當前點距離》d+g的元素出隊,取隊首轉移就可以了..算是一道不難不簡單的套路題qwq
#include
using
namespace
std;
typedef
long
long ll;
const
int n=500003;
const ll p=-1999999999;
int n,d,k,i,ans,l,r,x[n],a[n],mid;
ll seg[n*4];
inline
int read()while (c<'0' || c>'9');
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return flag*x;
}void build(int t,int l,int r)
void add(int t,int l,int r,int x,int val)
int mid=l+r>>1;
if (x<=mid) add(t<<1,l,mid,x,val);
else add(t<<1|1,mid+1,r,x,val);
seg[t]=max(seg[t<<1],seg[t<<1|1]);
}ll query(int t,int l,int r,int x,int y)
int check(int mid)
if (s>=k) return
1; }
return0;}
int main()
printf("%d",ans);
}
單調佇列:
#include
using
namespace
std;
const
int n=500003;
typedef
long
long ll;
ll x[n],s[n],f[n];
int n,k,i,q[n],h,t,d,l,r,ans,mid;
int read()while(c<48||c>57);
do x=(x<<1)+(x<<3)+(c^48),c=getchar();while(c>=48&&c<=57);
return f*x;
}void push(int x)
bool check(int g)
return0;}
int main()
printf("%d",ans);
}
洛谷P3957 跳房子
跳房子,也叫跳飛機,是一種世界性的兒童遊戲,也是中國民間傳統的體育遊戲之一。跳房子的遊戲規則如下 在地面上確定乙個起點,然後在起點右側畫 n 個格仔,這些格仔都在同一條直線上。每個格仔內有乙個數字 整數 表示到達這個 格仔能得到的分數。玩家第一次從起點開始向右跳,跳到起點右側的乙個格仔內。第二次再從...
洛谷P3957 跳房子
普及組的題.填坑來了。當年的我一眼二分 dp,現在都佩服起自己來了.然後我們就寫個二分,在check裡面寫單調佇列優化dp即可。然後就a了.1 include 2 include 3 include 4 5 typedef long long ll 6 const int n 500010 7 co...
題解 P3957 跳房子
題目鏈結 題目大意 給定 n 個格仔離原點距離以及權值,初始單次移動距離只能為 d 你可以花費 g 枚金幣使得單次移動距離變為 max d g,1 d g 內任意整數,問獲得權值至少為 k 最少需要花費多少枚金幣 單調佇列 分析 顯而易見答案具有單調性,因為花費金幣越多機械人越靈活,花費金幣少的可行...