题意:有一个键盘,你敲w
的时候就弹出uu
,你敲m
的时候就弹出nn
,其他正常。现在给你一个用该键盘敲出的字符串,问你原字符串有多少种可能。
思路:首先字符串中不可能出现w和m。对于连续的u和n,用dp求出这一段可能对应的原字符串个数。然后乘起来就好了。
题意:有n个城市, n ≤ 200 n\leq 200 n≤200,每个城市的坐标为 ( x i , y i ) (x_i,y_i) (xi,yi),你可以在一个城市花费 c i c_i ci 建造供电站,也可以通过修路把两个城市连接起来共享供电站,修路的花费是 ( k i + k j ) ∗ ( ∣ x i − x j ∣ + ∣ y i − y j ∣ ) (k_i+k_j)*(|x_i-x_j|+|y_i-y_j|) (ki+kj)∗(∣xi−xj∣+∣yi−yj∣),要求所有城市都能用上电的最小代价。
思路:首先, c c c 最小的城市一定要自己建供电站。接着有两种做法:1. 建完最小代价的城市后,用修路的代价更新其他城市的代价。此时,选取最小代价城市的结论依然成立,递归地添加所有城市;2. 建图,共n+1个节点,城市标号1-n,每个城市引一条边到0号节点,边权为c;城市内部边依据修路代价,求最小生成树。因为是完全图,推荐prim。两种做法复杂度均为 O ( n 2 ) O(n^2) O(n2)。
题意:有一个10*10的迷宫,你起初在左下角(0,0)位置,目标在(9,9)。在一个回合中你扔一个1-6的均匀骰子,结果为r你就前进r步,如果前进不了r步(超出迷宫边界)就呆在原地。前进规则有两条:
- 在一行内部前进,跨行时不同行之间蛇形排列,因此(9,9)是在左上角
- 有的位置有电梯,在前进r步之后你可以选择是否乘坐电梯,每个电梯有高度h,乘坐电梯意味着从(i,j)瞬移到(i+h,j)。乘坐电梯算在当前回合内。
问:从(0,0)到(9,9)所需回合数的期望。
思路:首先按蛇形给10*10方格里的位置标号0-99,用dp[i]表示从i号位置到达目标的期望操作数,dp[99]=0,答案就是dp[0]。假如没有电梯,我们身处i号位置,投骰子6种结果中有cnt种结果会让我们前进。那么:
d
p
[
i
]
=
1
+
1
6
⋅
(
Σ
j
=
1
c
n
t
d
p
[
i
+
j
]
+
Σ
j
=
1
6
−
c
n
t
d
p
[
i
]
)
dp[i]=1+\frac{1}{6}\cdot(\Sigma_{j=1}^{cnt}dp[i+j]+\Sigma_{j=1}^{6-cnt}dp[i])
dp[i]=1+61⋅(Σj=1cntdp[i+j]+Σj=16−cntdp[i])
整理一下:
d
p
[
i
]
=
1
c
n
t
⋅
(
6
+
Σ
j
=
1
c
n
t
d
p
[
i
+
j
]
)
dp[i]=\frac{1}{cnt}\cdot(6+\Sigma_{j=1}^{cnt}dp[i+j])
dp[i]=cnt1⋅(6+Σj=1cntdp[i+j])
如果有电梯的话,我们用f[i]表示i号位置乘坐电梯后的位置编号(如果该位置没有电梯,f(i)=i),将上式中的dp[i+j]都替换为min(dp[i+j], dp[f[i+j]])即可。
题意:给你两个数 l , r , 0 ≤ l ≤ r ≤ 1 0 9 l,r, 0\leq l\leq r\leq 10^9 l,r,0≤l≤r≤109。问有多少对(x,y)满足 l ≤ x , y ≤ r , x + y = x x o r y l\leq x,y\leq r,x+y=x\ xor\ y l≤x,y≤r,x+y=x xor y
分析:首先,两个数相加和异或的结果相同,等价于按位与的结果为0。根据最后一位只能是(0,0),(0,1),(1,0),我们可以得到
a
n
s
(
2
l
,
2
r
)
=
3
⋅
a
n
s
(
l
,
r
)
ans(2l,2r)=3\cdot ans(l,r)
ans(2l,2r)=3⋅ans(l,r)。这里为了映射方便,ans(x,y)定义左闭右开的区间[x,y)上满足要求的pair数。
所以,当x,y都是偶数时,我们可以递归求解ans(x,y)。如果x,y中有奇数的话,把边界单独处理就行了。在处理奇数的时候,需要一个函数f(x,y)高效地统计[0,y)区间内和x按位与结果为0的数的个数,实现如下:
int f(int a, int b) {
int ret = 0, zeroes = 0;
for (int i = 1; i <= b; i <<= 1) {
if (b & i) {
b ^= i;
if (!(a & b)) ret += (1 << zeroes);
}
if (!(a & i)) zeroes++;
}
return ret;
}