Hungry Student Problem
装箱问题
The Modcrab
贪心,只要能打就打
Boxes Packing
贪心,每个箱子放进比它大的箱子里面最小的
Almost Difference
Swapping Characters
列出所有可能的原始字符串,挨个试就行。看起来可能很多,其实不多。
首先随便找到两个不相同的字符串s1和s2(如果全相同,直接把开头两个字母换一下输出就行),比较它们有几位不同,如果超过4,直接输出-1。
对于这两个中的某一个字符串s1,它可能:1)交换了两个相同的字符,保持不变;2)交换了两个不同的字符。
首先把s1自己加入可能列表;如果交换后字符串发生了变化,即s1!=s,那么参与交换的两位中至少一个是那不超过4个的不同位之中的一个,一一列出共得到不超过4*n种可能情况。
然后一个一个验证
Clear The Matrix
动态规划:dp[i][j]表示 达成“把第i列左侧全部清掉,第i列~第i+3列的状态为j“ 的最小代价,j是16个格子的状态压缩,最终结果为dp[n][0]。
Yet Another Maxflow Problem
首先,把求最大流转换为求最小割。
这个图的最小割一定是这种形式的:在A侧选择至多1个点x,删除Ax到Ax+1的边;在B侧选择至多1个点y,删除By到By+1的边;再删除从A指向B的边中起点小于等于x终点大于y的边。
原因是这样的,首先如果在A侧删除了多条竖边,那么一定有一条是最靠近A1的,只要删掉这条边,下面的点就都没有流量了,所以无需删除,B侧同理。
然后删掉符合条件的横边。
设F(x,y)为两边分别选择x和y时的割的大小,显然F(x,y)=a[x]+b[y]+f(x,y),f(x,y)表示符合条件的横边。
因为只有A侧的竖边会发生改变,所以对于一个特定的x0,其b[y]+f(x0,y)的值是不变的,所以可以预先找到这些值中最小的那一个,记为best[x0]。
best的求法:首先假设A侧不删边,那么显然b[y]+f(x0,y)=b[y]。然后对A侧的点从上到下循环,当处理点xi时,从xi出发的各条边<yj,cj>会导致yj之前的b[y]+f(xi,y)值均增加cj,可以通过一棵线段树来进行这些操作。
求出best后,再使用另一棵线段树来维护a[x]+best[x],每次输出最小值即可。
为了便于理解和整个思路的和谐,可以增加两个虚拟的点An+1和B0,如图所示,也方便写代码。