如果不進行大量的練習,只是被動的聽課,那樣一點效果都沒有。acm很看投入,投入少想見成果,很難。更何況我們的演算法課才12周。
這兩天看了看搜尋的一些題目,我算是剛剛接觸搜尋,我覺得難度挺大,看透了一些題目之後就好很多了,那一陣學搜尋的時候沒理解。
本週還是主要對單調佇列和二分進行學習,二分還好,固定模板,固定思路,就是題目型別靈活多變,上午做的一道題我一直以為用貪心,沒去試,用的二分,過了,有空去用貪心試試。二分法挺靈活的。
poj2823
【題意】
移動區間(長度固定)最值問題。 【分析】這類思想在單調佇列優化思想中尤其重要:區間長度為k,求區間內的最大值,考慮第i個數和第j個數,j-i=要入隊資料a[i],刪除隊尾元素;當隊頭<=i-k時,刪除隊頭元素。
單調佇列: 加入找最小數,考慮順序a,b(b在a的後面),若b#include #include using namespace std;
const int n = 1100000;
int n,k;
int a[n];
int dandiao_que[n]; //單調遞減佇列(最大),單調遞增佇列(最小)
int head,tail;
//遞增
void min()
for(i = k-1; i < n; i++)
}//遞減
void max()
for(i = k-1; i < n; i++)
}int main()
poj-3250-bad hair day 題意:有 n
頭牛頭朝東站成一列。每頭牛有一定的高度,並且只能看到它右邊比他矮的牛的牛頭,直到被某頭高度大於等於它的高度的牛所擋住。計算每頭牛能看到的牛頭頂的數量之和
sample input
6 10 3 7 4 12 2 sample output
#include #include #include #define maxn 80050
#define ll long long
using namespace std;
ll q[maxn];
int main()
cout<#include const int m = 100001<<1;
int sum[m],q[m];
int main()
for(int i=2;i< n+k;i++)
sum[i] += sum[i-1];
head = rear = 0;
q[head] = 0;
max = int_min;
for(int i=1;i< n+k;i++) //列舉每個區間終點
}end = end>n ? end%n : end;
printf("%d %d %d\n",max,start,end);
}return 0;
}
hdu 4193 單調佇列將乙個序列形成乙個環,序列中的每個數字輪流作為起始端,問有多少個起點,可以使前1項,前兩項……前n項加和全都為非負數。
既然陣列是迴圈的,自然想到先複製一遍,然後求sum[i],列舉每乙個長度為n的區間,看最小值是否滿足即可。
#include #define n 2000002
int a[n],sum[n],que[n];
int main()
int nn = n << 1;
for(i = 1; i <= nn; ++i)
sum[i] = sum[i-1] + a[i];
int head = 0,tail = 0;
int res = 0;
for(i = 1; i < nn; ++i)
printf("%d\n",res);
}return 0;
}
hdu3474
題意: 有一環形項鍊,項鍊上有兩種珍珠分別用c,j來表示.現在問是否存在這樣的切割點,滿足以下條件:沿著該切割後的項鍊的一端依次取出珍珠,但手裡的c珍珠數必須時刻不少於手裡的j珍珠數.問這樣的切割點有幾個.
由n(10^6)個資料組成的圓環,資料為1和-1,問從乙個點開始順時針或逆時針,能遍歷完所有點,並且保證中間過程中sum>=0。
分析:首先暴力o(n^2)是不可行的。
假設從i點開始,這裡僅考慮向左,必須保證sum(j,i)>=0, i-n =0,即sum[i] - max(sum[j])>=0.
要求區間[i-n,i-1]最大值,維護單調遞減佇列即可。
#include#include#includeusing namespace std;
#define n 1000005
int t,sum[2*n],lab[2*n];
char le[2*n];
bool vis[2][2*n];
int front,rear;
void solve(int n,int d)
for(i=n;i<=2*n;i++)
}int main()
return 0;
}
廣告印刷 【問題描述】最近,afy決定給toj印刷廣告,廣告牌是刷在城市的建築物上的,城市裡有緊靠著的n(n<=400000)個建築。afy決定在上面找一塊盡可能大的矩形放置廣告牌。我們假設每個建築物都有乙個高度,從左到右給出每個建築物的高度h1,h2…hn,0【分析】考慮構造乙個單調非遞減佇列,從左至右,依次加入到佇列中,肯定會有元素出佇列,設當前要插入的數為a,要出佇列的數為b,必有b>=a,則b向右能到達的最遠距離就是b-a。注意在求解時,讓0先入佇列,這樣保證每個資料都會出佇列。同理,左極限也可求出。
#include #define maxn 1000000
int h[maxn+5]; //建築物的高度
int n; //建築物的數目
int mq[maxn+5]; //單調佇列,對內元素為建築物高度的下標
int left[maxn+5]; //left[i]:在第i個建築物左側,不比它的高度小的建築物數量
int right[maxn+5]; //right[i]:在第i個建築物右側,不比它的高度小的建築物數量
void calcleft()
left[i] = i - mq[rear-1] - 1;
mq[rear++] = i; }}
void calcright()
right[i] = mq[rear-1] - i - 1;
mq[rear++] = i; }}
int maxrectarea()
} return maxarea;
}int main()
h[0] = h[n+1] = -1;
calcleft();
calcright();
for (i = 1; i <= n; i++)
cout << endl;
for (i = 1; i <= n; i++)
cout << endl;
cout << maxrectarea() << endl;
} return 0;
}
acm週末學習總結
搜尋是萬能演算法 如何找所有解?列舉。列舉的方法?遞迴。遞迴的組合?搜尋。廣搜while not queue.empty begin 可加結束條件 tmp queue.top 從tmp迴圈拓展下乙個狀態next if 狀態next合法 then begin 生成新狀態next next.step t...
acm週末學習總結
這週做了洛谷上面的題目,還是發現很多自己的不足,最大的問題是思路不清晰。細節不到位。最近幾周把精力集中在acm上,要為進入校隊而努力了!然後今天和乙個舍友組了個隊打了一場比賽,最後就是有5道題有思路卻只ac了3道,並查集的題目我們都不會,用別的方法沒做出來,暴力不是總會出奇蹟。細節,還是得注意細節。...
週末學習總結
關於下午的網路賽,我們的水平是3題,但是只出了2題。最後5分鐘打表找了e的規律,我們還天真的以為找到了規律。殊不知我們找的規律已經超過了題目所給的範圍。一開始隊友手快用stl的deque寫完交,超時,我玄學優化交後發現記憶體超限。關於stl,要學習的還有很多很多,我們覺得用起來很方便,全都封裝好了,...