第四題還沒做…先貼前三個題的。有一支
n個人的隊伍要過一座限重為
w的橋,我們規定這支隊伍過橋時只能分組過,即當一組全部過去後,下一組才能接著過。給定每個隊員的重量wi
和過橋時間ti
,一組人的過橋時間為花費時間最多的人的時間。問如何分組使得總的過橋時間最短。
input
100 3
24 60
10 40
18 50
output42
資料範圍告訴我們應該考慮狀壓dp。用 d
p[s]
表示s中的人還未過河所用的時間,則有:dp
[s]=
maxt(a),w(a)分別表示通過的時間最大值和重量總和。
現在問題轉化為如何列舉集合的子集。如果用樸素的列舉只能拿到70分左右。從《挑戰程式設計競賽》上學到的乙個方法則可以降低複雜度:
sub = s;
do while (sub > 1)
這樣處理sub就列舉了2s
。總的複雜度可以用:∑1
≤i≤n
(ni)
2i打個表就知道能o(能過)…
#include
using
namespace
std;
int dp[1
<<18], w, n;
int w[20], t[20];
int a[1
<<18], m[1
<<18];
int dfs(int s)
while (sap > 1);
//cout << s << " --> " << dp[s] << endl;
return dp[s];
}int main()
定義
f為斐波那契數列,被定義為:f0
=0,f
1=1f
n=fn
−1+f
n−2,
n>1而
g為乙個序列,定義為:gi
=∑a1
+a2+
...+
am=i
,ak>0∏
j≤mf
aj對於給定的n,求
gnmod109+
7。input
3
output5
3=
1+1+
1f1×
f1×f
1=1=
2+1f
2×f1
=1=1
+2f1
×f2=
1=3f
3=21
+1+1
+2=5
首先看樣例解釋很容易發現乙個遞推式:gn
=∑1≤
i≤nf
i×gn
−i打表找規律會發現 ∀i
≥3,g
i=2g
i−1+
gn−2
。現在來證明一下:首先可以證明g1
=1,g
2=2⇒
g1+g
2=g3
+1,然後用歸納法2g
n−1+
gn−2
=∑1≤
i≤n−
12fi
gn−1
−i+∑
1≤i≤
n−2f
ign−
2−i=
∑1≤i
≤n−3
fi(2
gn−1
−i+g
n−2−
i)+2
fn−1
g0+2
fn−2
g1+f
n−2g
0=∑1
≤i≤n
−3fi
gn−i
+2fn
−1+3
fn−2
(1)2
fn−1
+3fn
−2=2
fn−2
+fn−
1+fn
=∑n−
2≤i≤
nfig
n−i因此:(1
)=gn
原命題得證。然後只需要矩陣[2
110]
做快速冪取模就好了。注意特判。
#include
using
namespace
std;
struct matrix
friend matrix operator * (const matrix &a, const matrix &b)
};matrix i()
matrix power(const matrix &a, long
long n)
int main()
if (n == 1)
matrix m; m.a[1][1] = 2, m.a[1][2] = 1, m.a[2][1] = 1;
m = power(m, n-1);
cout
<< m.a[1][1] << endl;
return
0;}
給定
n個回文串,s1
,s2,
...,
sn。求有多少有序整數對 (i
,j) 使得si
sj仍為回文串。
input
7
2 aa
3 aba
3 aaa
6 abaaba
5 aaaaa
4 abba
output14
當時考場上sdf乙個女選手怒而碾過orz……
我們用s−1
表示s的反串。容易知道「穿脫原則」: (a
b)−1
=b−1
a−1 在這裡成立。
考慮兩個回文串a,
b,根據定義有:a=
a−1,
b=b−
1⇒ba
=b−1
a−1滿足題目中條件為:ab
=(ab
)−1按照穿脫原則展開:ab
=b−1
a−1也就是:ab
=ba所以原問題轉化為了求ab
=ba的對數。考慮用多項式雜湊:ha
sh(a
b)=h
ash(
a)×b
ase|
b|+h
ash(
b)ha
sh(b
a)=h
ash(
b)×b
ase|
a|+h
ash(
a)ha
sh(a
)bas
e|a|
−1=h
ash(
b)ba
se|b
|−1可以看到兩側都變成了只含有乙個量的表示式,成功地將兩個量的關係轉化成了乙個量的性質,除法可以用模大素數下的乘法逆元處理,因此就可以丟進hash算了。
然而乙個問題是這樣做衝突嚴重。如果懶得寫拉鍊怎麼辦呢?乙個有趣的方法是考慮ab
=ba必然有a[
|a|]
=b[|
b|],而且他們是最高位,計算hash的時候乘了乙個巨大的數。因此我們可以把hash值乘上這一位的ascii,就可以很大程度避免衝突了。
至於base的選取..親測37效果最好…不知道為什麼,可能是資料的緣故吧…
#include
using
namespace
std;
long
long mod = 2016122203ll, base = 37;
long
long power(long
long a, long
long n)
long
long inv(long
long a)
long
long hash_val(char str)
maplong, int> hash_set;
int n, w;
char str[2000005];
long
long cnt = 0;
inline
int read()
return a;
}inline
void read(char str)
str[i] = '\0';
}int main()
cout
<< cnt*2+n << endl;
return
0;}
2011多校九部分解題報告
1005 hdu3924題意每個樹有三個子樹,求第n個數的形狀。先求出不同個數的x方法數,然後先計算所有x的個數,然後不斷地遞迴算出左中右三個子樹的個數。rejudge了。注意左子樹相同時,中子樹的個數多的不一事實上在中子樹個數少的後面,因為此時要看左子樹的狀態 rejudge後wa include...
2020 4 19個人賽部分解題與補題報告
題意 給n,若有n個數能按規定的排序方式輸出 1,若不可以輸出反例 類似於冒泡法排序,但沒有內層排序 只有n 1或n 2的時候可以正確排序 include include include using namespace std intmain else cout 2 3 1 return0 view...
第三部分 POJ 1007 解題報告
poj 1007 dna sorting 問題描述 序列 未排序程度 的乙個計算方式是元素亂序的元素對個數。例如 在單詞序列 daabec 中,因為d大於右邊四個單詞,e大於c,所以計算結果為5。這種計算方法稱為序列的逆序數。序列 aacedgg 逆序數為1 e與d 近似排序,而序列 zwqm 逆序...