題目:
有一口井,井的高度爲N,每隔1個單位它的寬度有變化。現在從井口往下面扔圓盤,如果圓盤的寬度大於井在某個高度的寬度,則圓盤被卡住(恰好等於的話會下去)。
盤子有幾種命運:1、掉到井底。2、被卡住。3、落到別的盤子上方。
盤子的高度也是單位高度。給定井的寬度和每個盤子的寬度,求最終落到井內的盤子數量。
如圖井和盤子信息如下:
井:5 6 4 3 6 2 3
盤子:2 3 5 2 4
最終有4個盤子落在井內。
輸入
第1行:2個數N, M中間用空格分隔,N爲井的深度,M爲盤子的數量(1 <= N, M <= 50000)。 第2 - N + 1行,每行1個數,對應井的寬度Wi(1 <= Wi <= 10^9)。 第N + 2 - N + M + 1行,每行1個數,對應盤子的寬度Di(1 <= Di <= 10^9)
輸出
輸出最終落到井內的盤子數量。
輸入樣例
7 5 5 6 4 3 6 2 3 2 3 5 2 4
輸出樣例
4
思路:
第一次思路是從第一個圓蓋開始往裏邊填,一直填到不能填,時間複雜度是O(N^2),提交上去超時,看了博客才知道要逆向考慮,首先分析可知,如果盤子可以落到n,那麼比n淺的深度的寬度必須都大於等於n位置的寬度,那麼我們可以預處理一下井,使得井從深往淺,寬度遞增。這樣,我們填圓蓋時可以直接從最底層開始填充,一直填到結束出結果,這樣的複雜度爲O(n)。
代碼:
#include<stdio.h>
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int a[50010]= {1000000010},sum=0,k=n;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(a[i]>a[i-1])
a[i]=a[i-1];
}
for(int i=1; i<=m; i++)
{
int x;
scanf("%d",&x);
for(;k>0;k--)
{
if(a[k]>=x)
{
k--;
sum++;
break;
}
}
}
printf("%d\n",sum);
return 0;
}