Time of Update: 2018-12-07
最簡單的最大流演算法,不斷搜尋增廣路增廣。這是很不划算的演算法,因為效率太低了,隨便一個資料都能把它卡住。雖然現在10分鐘就能打出一個沒有錯誤的SAP,花很長時間搞出這個很不划算。但是,我不能死記一個進階的演算法而連最基礎的演算法都打不出來。競賽雖然功利,但是學習演算法也並不是完全為了競賽。在網上找,只能找到幾個,因為搞競賽至少也要用個EK,很少有人做題用DFS的。找到的幾個,有的寫得太醜了,有的只是給出了過程,反正找不到滿意的。因為過程倒是很好理解,自己嘗試打了一下,但是調不過去。最後在htt
Time of Update: 2018-12-07
文章目錄 定義樸素的枚舉用歸併排序思想解決用支援區間修改的資料結構解決 定義對於一個包含N個非負整數的數組A[1..n],如果有i < j,且A[ i ]>A[ j ],則稱(A[ i] ,A[ j] )為數組A中的一個逆序對。例如,數組(3,1,4,5,2)的逆序對有(3,1),(3,2),(4,2),(5,2),共4個。
Time of Update: 2018-12-07
抽屜原理。。早就知道了,只是沒有切過題,今天碰上了一道,果斷刷掉其實n個數一定可以找出一些數或某個數的和能被n整除取sum[i]為前i個數的和,對n取餘。n個數對n取餘,下面兩個結論必有一個成立:有兩個餘數是相等的,有一個餘數是1其中任何一個結論的成立都表示存在一些數的和能被n整除View Code 1 #include<stdio.h> 2 #include<string.h> 3 int sum[10010]; 4 int mod[10010]; 5 int re[
Time of Update: 2018-12-07
枚舉兩個多邊形的兩個點組成的直線,判斷能與幾個多邊形相交因為最佳的直線肯定可以經過某兩個點(可以平移到頂點處),所以暴力枚舉兩個點就好了View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const double eps = 1e-8; 7
Time of Update: 2018-12-07
很明顯的二分匹配,只是直接把可以組成的兩個正方形的地方連邊的話會重複計算,結果是最大匹配數的兩倍,但方案不好輸出但由於每兩個相鄰的正方形的(x+y)奇偶性(行和列相加)是不同的,所以,就可以把奇的放左邊偶的放右邊(或倒過來,都可以)匈牙利之後直接輸出匹配數和方案就好了View Code 1 #include<stdio.h> 2 #include<string.h> 3 #include<vector> 4 using namespace std; 5
Time of Update: 2018-12-07
其實可以二分的,聽說直接輸入一扇門的資訊,做一次SCC也能爆過,就直接暴力了,呵呵~每個門有兩把鎖,這就有了一種關係,假設兩把鎖是a,b,那麼不開a就一定要開b,不開b就一定要開a,即b'->a,a'->b;另外還有n對矛盾關係,用了a鑰匙就不能用b鑰匙,a->b',b->a'然後,強連通求解#include<stdio.h>#include<string.h>#include<vector>#include<algorithm&
Time of Update: 2018-12-07
O(nlogn)的演算法關鍵是它建立了一個數組temp[],temp[i]表示長度為i的不下降序列中結尾元素的最小值,用top表示數組目前的長度,演算法完成後top的值即為最長不下降子序列的長度。 設當前的以求出的長度為top,則判斷num[i]和temp[top]: 1.如果num[i]>=temp[top],即num[i]大於長度為top的序列中的最後一個元素,這樣就可以使序列的長度增加1,即top++,然後現在的temp[top]=num[i];
Time of Update: 2018-12-07
簡單二分匹配,注意,輸出的是n-最大匹配數#include<stdio.h>#include<string.h>#include<math.h>int match[110];bool map[110][110];struct point{double x,y;}p[110],hole[110];double dis(point a,point b){return
Time of Update: 2018-12-07
簡單的方法來自http://poj.org/showmessage?message_id=156697#include<stdio.h>#include<string.h>int dp[100010];int num[110],v[110];int used[100010];int main(){int n,m,i,j;while(scanf("%d%d",&n,&m),(n||m)){for(i=0;i<n;i++)
Time of Update: 2018-12-07
三種背包,每組至少、至多取一個或隨意取多少注釋在代碼中#include<cstdio>#include<cstring>int dp[110][110];int max(int a,int b){return a>b?a:b;}int main(){int
Time of Update: 2018-12-07
#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;#define SIZE 1010const int inf = 100000000;struct node{int s,t,f,w;int next;}edge[100010];int head[2010];int mincost,tot;int s,t,pre[2010
Time of Update: 2018-12-07
這兩題基本是一樣的,類比球隊之間對戰、晉級,整個過程就是一顆滿二叉樹,最終根節點的位置就是冠軍這道題目有一個很神奇的地方,改天我會仔細解釋,現在先留著代碼View Code 1 #include<stdio.h> 2 #include<string.h> 3 double p[130][130]; 4 double dp[130][8]; 5 int main(){ 6 int i,j,t,cases=1; 7 char str[20][20]; 8
Time of Update: 2018-12-07
轉載。。題目連結:http://poj.org/problem?id=2349這個問題是最小產生樹的問題假設d 已知,把所有鋪設線路的村莊串連起來,構成一個圖。需要衛星裝置的台數就是圖的連通支的個數。 d越小,連通支就可能越多。 那麼,只需找到一個最小的d,使得連通支的個數小於等於衛星裝置的數目。把整個問題看做一個完全圖,村莊就是點,圖上兩點之間的邊的權值,就是兩個村莊的直線距離。 只需在該圖上求最小產生樹,d 的最小值即為第 K 長邊! 因為:最小產生樹中的最長k-1條長邊都去掉後,正好將原
Time of Update: 2018-12-07
終於調出來了,理解之後其實很簡單,但是一些細節總是沒處理好。直到現在還有一點疑問在。兩者的漸進複雜度都是O(ELogV+VLogV),因為邊調整了E次,刪除最小元V次,二元堆積的操作都是LogV層級的。事實上兩個演算法很相似,Prim只是鬆弛操作和Dijksrra還有記錄ans的方式不同。在演算法導論上看到,Kruskal演算法是ELogE的即可以約成E*2LogV即ELogV,漸進意義上是和Prim一樣的。平時很少看見用heap最佳化的Prim和Dijkstra,可能是因為Kruskal和SP
Time of Update: 2018-12-07
無向圖的最小環:從某個點出發走回自己的最短路徑,路徑上至少有三個點搜尋做法:View Code 1 //PKU 1734 無向圖的最小環,搜尋做法 2 #include<stdio.h> 3 #include<vector> 4 #include<string.h> 5 using namespace std; 6 const int N = 110; 7 const int inf = 1e8; 8 struct node{ 9 int to,w;
Time of Update: 2018-12-07
dp[i]表示現在存在i個吸血鬼要達成目標(全為吸血鬼)天數的數學期望假如現在再增加一天,這一天可能會增加一個吸血鬼,p1*(dp[i+1]+1)表示接下來的一天增加了一個吸血鬼,所以為(dp[i+1]+1),還有一種可能就是沒有增加吸血鬼,機率自然是(1-p1)dp[i]+1表示接下來的一天沒有增加吸血鬼,但向後推移了一天因此dp[i]這個狀態可以轉移到dp[i+1]+1,機率為p1dp[i]+1 機率為(1-p1)所以dp[i]=(dp[i+1]+1)*p1+(dp[i]+1)*(1-p1)
Time of Update: 2018-12-07
POJ 2777/* 線段區間染色,並統計區間內顏色個數 因為顏色不多可以用位元運算,但是我還是用數組記錄 注意:C的>>和<<運算子比+ - 低,x << 1 + 1來表示x * 2 + 1是錯的,必須套上括弧 即(x << 1) + 1,已經不止一次犯這個錯誤了。 精簡了一下代碼。但還是上百行…… 2011-07-29 07:59*/#include <stdio.h>#define MAXN 1
Time of Update: 2018-12-07
矩陣相乘模板#include <cstdio>#include <cstring># define ld __int64struct Matrix{ld a[2][2];void init(){ a[0][0]=a[1][0]=a[0][1]=1;a[1][1]=0;}};Matrix matrix_mul(Matrix a,Matrix b){int i,j,k;Matrix
Time of Update: 2018-12-07
注意,求的是最大的機率,所以先求出不能被錄取的最小的機率p,然後直接1-p即可WA了兩次原因:初始化的時候dp[0]沒有賦值#include<stdio.h>#include<string.h>double dp[10010];int a[1010];double b[1010];double min(double a,double b){return a<b?a:b;}int main(){int
Time of Update: 2018-12-07
一圈的點從0到n-1順次圍起來,題目中給出m條links,要求你把這些link對應的點連起來,問是否存在一種可能使得連完後不存在相交的兩條線另外,連線有兩種連法,內部相連與外部相連,而且題目保證 Every point will have at most one