2016長樂夏令營 Day9

2021-07-15 04:35:06 字數 3587 閱讀 4423

t1:

帶權並查集。每個約束看做一條x連向y的邊,邊權為x+y = c

對於乙個x,可能有多個y與他有關係,間接可以算出y與y』的關係,那麼邊權就記為y - y'

每次加入條件,就看看是否衝突

細節詳見**

據說正解是差分約束??苟蒻是真不會。。

#include#include#includeusing namespace std;

const int maxn = 1e3 + 10;

int n,m,k,fa[maxn*2],va[maxn*2],x[maxn],y[maxn],c[maxn];

int fat(int now)

int main()

}else

} if (flag) printf("yes\n");

} return 0;

}

t2:

如果n == 1

以任意位置i作為第乙個,那麼還需要向上刷i-1次,向下刷m-i次

我們可以在m-i次的過程中任意插入i-1個向上刷的操作

即m-i個數之間放入i-1塊隔板(板可以在序列前、後、中間任意位置)

板與物品共有m-i+i-1 = m-1個 於是c(m-1,i-1)

列舉i,統計答案

如果 n == 2

f[i]:刷一面2*i的牆,強制規定第一次必須刷第一行的方案數

f[i] = 2*f[i-1]*(2*i-1)

首先,第一次有兩種刷法,然後要刷完底下2*(i-1)個,而還有第一行的另乙個沒有刷,這塊牆壁可以在刷底下2*(i-1)塊的過程中的任意時刻刷,於是有(2*i-1)個時刻可以刷

統計答案

第一次任意在第i行刷

只刷上面有f[i-1]種,只刷下面有f[m-i]種

上下都刷(隔板法)有c(m-2,2*(i-1))*f[i-1]*f[m-i]種

在這個過程中隨時可以插入刷i行的另一塊的操作

所以 2*c(m-2,2*(i-1))*f[i-1]*f[m-i]*(2*m-1)

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

const int maxn = 3010;

typedef int ll;

const ll mo = 1000000007ll;

ll c[maxn*2][maxn*2],f[maxn];

int n,m,t;

int main()

cin >> t;

while (t--)

else

int ans = ans;

printf("%d\n",ans);

} return 0;

}

t3:

先建立ac自動機

考慮在ac自動機上dp

f[i][j]:原串走到第i個位置,ac自動機走到第j個點,最少需要更改幾個

為了最小化ans,需要盡量貼著原序列走,儘管這樣很容易碰到禁止的序列

列舉j的四個兒子,如果該兒子等於i+1位置上的字母

f[i+1][son] = f[i][j]

否則 f[i+1][son] = f[i][j]+1

當然,原來的ac自動機中有些點一定不能到達的,標出來即可

在轉移失配邊時要注意用|運算,標出字尾為禁止序列的情況(詳見**)

最後,ac自動機以1為根,對於走到0的情況,四個孩子都寫1,否則會出錯啊gg

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

const int maxn = 2e3 + 20;

const int inf = ~0u>>1;

struct ac

}tree[maxn];

struct p

};int g[maxn][maxn];

int n,len,cur = 1,ans = inf,num[maxn],f[maxn];

char c[maxn];

queue q;

queue q;

int change(int pos)

int main()

tree[x].va = 1; }

q.push(1); for (int i = 1; i <= 4; i++) tree[0].ch[i] = 1;

while (!q.empty())

int v = f[k];

while (v && !tree[v].ch[i]) v = f[v];

f[u] = tree[v].ch[i];

tree[u].va |= tree[f[u]].va;

q.push(u);

} }scanf("%s",c+1); len = strlen(c+1);

for (int i = 1; i <= len; i++) num[i] = change(i);

for (int i = 0; i <= len; i++)

for (int j = 0; j <= cur; j++)

g[i][j] = inf;

q.push(p(0,0)); g[0][0] = 0;

while (!q.empty())

if (num[k.x+1] != i && g[k.x+1][tree[k.y].ch[i]] > g[k.x][k.y] + 1)

} }

for (int i = 0; i <= cur; i++) ans = min(ans,g[len][i]);

if (ans == inf) cout << -1;

else cout << ans;

return 0;

}

2016長樂夏令營 Day4

t1 模擬。開一排const char include include include include include include include include includeusing namespace std const char n0 5 3 const char n1 5 3 con...

開源夏令營(9)總結

category.php的製作 php 功能 判斷是否為分類目錄別名,如果不是,則使用category default.php 分類目錄模板 如果是,則使用對應的分類目錄模板 if is category pic elseif 結束 如果訪問其他分類,則使用category default.php ...

演算法營day9

題目描述 乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。思路 如果乙個陣列中,只有乙個數字出現一次的話,求這個數的?將序列中的所有數字異或,因為相同的數字異或會為0,乙個不為0的數字異或還是這個數字本身。這個題可以轉換為上述的題,將序列中的所有數字異或,...