蘋果(apple)二分答案+貪心斷定

蘋果(apple)
【題目背景】
儘管題目名是蘋果,可是此題和蘋果沒有任何關係。
這是爲何呢?
【題目描述】
考慮一個樹形結構的信號傳遞網絡,初始存在一個信號源點,記其標號爲 0。
樹上有兩種節點,一種爲信號中繼點,用來接收父親節點的信號並分發給它的兒子
們。另外一種爲信號接收點,僅能接收父親節點的信號但不能向下傳遞。
對於一箇中繼點 i ,它能最多將信號分發給 ai 個兒子。對於一個接收點 i,它能生
效僅當它與初始源點間的中繼點個數不超過 bi。
對於 bi = 0 的接收點,只能直接鏈接在源點上。源點能夠視做一種特殊的中繼點,
它僅能將信號分發給 1 個兒子。
如今給出 n 箇中繼點和 m 個接收點,小 Z 想知道最多能夠使多少個接收點接受到
信號。
注意你不. 一. 定. 須要使用全部 n + m 個節點。
【輸入格式】
從文件 apple.in 中讀入數據。
輸入的第一行包含兩個正整數 n, m,保證 1 ≤ n, m ≤ 2 · 105,含義如上所述。
輸入的第二行包含 n 個正整數 a1, a2, ..., an,表示 n 箇中繼點。2 ≤ ai ≤ 2 · 105
輸入的第三行包含 m 個正整數 b1, b2, ..., bm,表示 m 個接收點。0 ≤ bi ≤ 2 · 105
【輸出格式】
輸出到文件 apple.out 中。
輸出一行一個正整數,表示最多能夠使多少個接收點接受到信號。
【樣例 1 輸入】
3 6
4 2 2
1 2 3 2 1 1
【樣例 1 輸出】
5
【樣例 2】
見選手目錄下的 apple/apple2.in 與 apple/apple2.ans。
【子任務】
測試點 n m 特殊性質
1 ≤ 3 ≤ 3 無
2 ≤ 10 ≤ 10 無
3 ≤ 20 ≤ 20 無
4 ≤ 20 ≤ 20 bi = i
5 ≤ 200000 ≤ 200000 bi 互不相同
6 ≤ 200000 ≤ 200000 ai = 2
7 ≤ 50000 ≤ 50000 無
8 ≤ 200000 ≤ 200000 無
9 ≤ 200000 ≤ 200000 無
10 ≤ 200000 ≤ 200000 無ios

 

題解見註釋網絡

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 2 * 100000 + 10 ;
int n,m,a[maxn],b[maxn],ans,now[maxn];
bool cmp(int x,int y){return x>y;}
//貪心策略 先放不得不放的接收器 ,在選擇分發能力強的中繼器 
bool judge(int x)
{
    memset(now,0,sizeof(now));
    int top(0),flor(1);now[flor]=1;
    for(;;){
        while(x && now[flor] && b[x]<flor) x--,now[flor]--;//若是還有剩餘位置,且還有接收七器 
        if(!x)           return true;//若是全部接收器都用了,二分的答案可行; 
        if(x && !now[flor]) return false; //若是還有剩的接收器,且沒有剩餘位置了,不可行 
        while(now[flor] && top<n)//統計這層的位置放入中繼器,統計下層位置 
            now[flor+1]+=a[++top],now[flor]--;
        now[flor+1]+=now[flor];//下層位置加上這層還還剩的位置 
        flor++;
    }
}
int main()
{
    freopen("apple.in","r",stdin);
    freopen("apple.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=m;i++) scanf("%d",&b[i]);
    sort(a+1,a+1+n,cmp);//從大到小排序 ,貪心得想,二分選的接收器可大的來; 
    sort(b+1,b+m+1,cmp);
    int l=1,r=m;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(judge(mid)) l=mid+1,ans=mid;
        else           r=mid;
    }
    cout<<ans<<endl;
    return 0;
}
相關文章
相關標籤/搜索