Time of Update: 2018-12-05
#define N 10int num[N];int dp[120010];int V;//容量void zeroone(int cost,int val){//費用,價值 int i; for(i=V;i>=cost;i--){ if(dp[i]<dp[i-cost]+val){ dp[i] = dp[i-cost]+val; } }}void complete(int cost,int val){//費用,價值
Time of Update: 2018-12-05
可以KM,也可以費用流,最近學費用流,所以用一下,debug真浪費時間,以為spfa有問題,原來是計數時出錯。。。囧啊,菜啊,話說poj 2516到現在還不知道wa哪裡,抓狂啊!!!#define inf 1<<30#define N 222int cap[N][N];int cost[N][N];int pre[N];int dis[N];bool vis[N];int minc;char str[110][110];int min(int a,int b){return
Time of Update: 2018-12-05
http://poj.org/problem?id=3071題意是又2^n支球隊,球隊兩兩之間進行比賽,例如開始時0-1, 2-3, 4-5, 6-7...............然後晉級後又是相鄰兩兩之間比賽,問最大可能的勝者編號。方法:機率dp。設dp[i][j]表示第i輪j隊勝的機率, 其中dp[i][j] +=
Time of Update: 2018-12-05
因為有兩條不同路徑,所以可以這樣構圖:超級源點s->1,容量為2,邊權為0,n->超級匯點t,容量為2,邊權為0,其他的點容量為1,邊權是輸入的資料,這樣就保證了肯定有兩條不同的路徑,而且模型肯定滿流,因為這題有重邊,所以不能用鄰接矩陣,只能用鄰接表#define inf 1<<30#define N 10050struct node{ int u,v,cap,w; int next;}e[N*6];int head[N/10];int
Time of Update: 2018-12-05
http://poj.org/problem?id=1141dp求最優解。#define N 110char str[N];int dp[N][N];//i到j之間插入的最小字元數int tag[N][N];//記錄需要插入字元的位置void gao(int n){ int i,j,k; for(i=0;i<=n;i++){ for(j=0;j<=n;j++){ dp[i][j] = 0; }
Time of Update: 2018-12-05
歐幾裡得LL gcd(LL a,LL b){return (b==0) ? a : gcd(b,a%b);}擴充歐幾裡得int ex_gcd(int a,int b,int &x,int &y){//返回的是最大公約數 if(b==0){ x = 1; y = 0; return a; } int d = ex_gcd(b,a%b,x,y); int t = x; x = y; y = t-a/b*y;
Time of Update: 2018-12-05
不可重疊最長重複子串(pku1743)給定一個字串,求最長重複子串,這兩個子串不能重疊。演算法分析:這題比上一題稍複雜一點。先二分答案,把題目變成判定性問題:判斷是否存在兩個長度為k 的子串是相同的,且不重疊。解決這個問題的關鍵還是利用height 數組。把排序後的尾碼分成若干組,其中每組的尾碼之間的height 值都不小於k。例如,字串為“aabaaaab”,當k=2 時,尾碼分成了4 組,5所示。容易看出,有希望成為最長公用首碼不小於k
Time of Update: 2018-12-05
相對於一般的網路流,有上下界的網路流的某些邊多出了流量下界的限制,如邊u->v,上下界為high、low,如果有流經過這條邊,這個流必須在[low,high]這個區間內。這類題目主要要求解決下面三個問題,“有源匯、無源匯的可行流”、“有源匯的最大流”、“有源匯的最小流”,注意這裡所說的源匯是原網路中的源匯,分別記為s、t。 這類題目的痛點在於下界的限制很難處理,我們將所有有下界限制的邊中分離出“必須邊”來單獨做考慮,所謂“必須邊”就是必須要滿流的邊,如上述的邊,我們可以拆成兩條邊,第一條
Time of Update: 2018-12-05
可以作為模板#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>
Time of Update: 2018-12-05
先二分答案,然後將尾碼分成若干組,判斷的是有沒有一個組的尾碼個數不小於k。如果有,那麼存在k 個相同的子串滿足條件,否則不存在。這個做法的時間複雜度為O(nlogn)。這裡有一個地方要注意的,就是計數每一組的時候cnt初始值為1,因為height數組是兩兩之間比較的,當有1個height滿足後就相當於有兩個尾碼滿足。#define N 1000010#define maxn 20010int
Time of Update: 2018-12-05
A 水#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <cstdio>#include <math.h>#include <iomanip>#include
Time of Update: 2018-12-05
spoj694 http://www.spoj.pl/problems/DISUBSTR/spoj705 http://www.spoj.pl/problems/SUBST1/兩道題差不多,只是705的資料大一點而已,用倍增演算法沒壓力,繼續套模板貼一下羅大牛的思路,說白了就是∑每個尾碼長-height。不相同的子串的個數(spoj694,spoj705)給定一個字串,求不相同的子串的個數。演算法分析:每個子串一定是某個尾碼的首碼,那麼原問題等價於求所有尾碼之間的不相同的首碼的個數。如果所有的尾
Time of Update: 2018-12-05
首先講講A*演算法吧。眾所周知,A*演算法就是啟發學習法搜尋,基本形式就是這樣:f(x)=g(x)+h(x);其中f(x)代表在x點所需要的總代價,而g(x)代表:從源點到x點已經耗費的實際代價,h(x)代表從x到終點需要的估計代價,這個函數是一個估計值.而從x到終點真正需要的代價為h*(x),在整個啟發學習法搜尋中我們必須保證h(x)<=h*(x);不然的話會由於對當前的估價值過高,則會引起答案的錯誤。構建A*的關鍵在於準確的規劃一個h(x)函數,使得接近h*(x),這樣的搜尋會使得答案
Time of Update: 2018-12-05
媽的!!!wa死,不知道死在哪裡。。。先放著#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <cstdio>#include <math.h>#include
Time of Update: 2018-12-05
MLE了...囧,不過演算法是正確的#define maxn 2000010int wa[maxn],wb[maxn],wv[maxn],wss[maxn];int r[maxn],sa[maxn];int cmp(int *r,int a,int b,int l){return r[a]==r[b] && r[a+l]==r[b+l];}void da(int *r,int *sa,int n,int m){//n要加1 int
Time of Update: 2018-12-05
int max(int a,int b){return a>b?a:b;}int dp[110][110];int main(){ int n,t; while(scanf("%d%d",&n,&t) != -1){ int i,j,k; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++){ int m,s; scanf("%d%d",&
Time of Update: 2018-12-05
http://poj.org/problem?id=2044#define N 366bool flag[8][8][8][8][10][N];//前四個是四個角的狀態,第五個是雲的左上方的位置,最後一個是第幾天int day[N];int n;int d[9][2] = { {0,0},//九個位置 {-1,0},{-2,0}, {1,0},{2,0}, {0,-1},{0,-2},
Time of Update: 2018-12-05
http://acm.ustc.edu.cn/ustcoj/problem.php?id=1280這題是中國科大“百分點科技杯"ACM除夕挑戰賽 的題目,當時做不出,後來想了一下,TLE1次,wa一次就過了這題去掉最小費用和的邊使得最短路變長,方法是先求一次最短路,然後建新圖,圖中存在的邊若且唯若(u,v) dis[u]+w(u,v)=dis[v],題目就變成求切掉最小的邊,切完後最短路必然變大,然後最小割=最大流就可做了,具體實現上就要使得if(dis[u] + e[i].w !=
Time of Update: 2018-12-05
直接暴力回溯。struct node{ int x,y;}p[100];int cnt;int g[10][10];bool ok;void out(){ int i,j; for(i=0;i<9;i++){ for(j=0;j<9;j++){ printf("%d",g[i][j]); } puts(""); }}void dfs(int k){ if(k == cnt){
Time of Update: 2018-12-05
題意:分物品,使得兩份的價值差最小。方法:相當於求容量為sum/2的最大價值,所以,所需費用=當前物品價值#define N 55int v[N],m[N];int dp[50*50*100+100];int V;//容量void zeroone(int cost,int val){//費用,價值 int i; for(i=V;i>=cost;i--){ if(dp[i]<dp[i-cost]+val){ dp[i] =