A回 完全背包转01背包,01背包的二进制优化。
对于N种商品,每种Mi件,收益为Pi,体积为Vi。
可以看做有sigma(M)件这样的商品,每种商品只有要或不要两种状态,于是完全背包转化为01背包。
此时的时间复杂度为O( sigma(Mi)*V ),二进制可以优化到O(sigma(log(Mi) )*V );
对于[1,n]区间内的所有整数可以有2^0,2^1,.,2^i, 以及 n-2^i 组合得到,其中i满足2^i <= n 且 n < 2^(i+1)。
也就是说对于某种有Mi件的商品,我们可以用log(Mi)件来等价替换。
B去 字符串Hash + DP
DP公式显而易见:
若前缀 i 为回文,那么dp[i] = dp[i/2] + 1;
否则 dp[i] = 0;
最终答案为sigma(dp[i])。
难点在于求解快速判断某个前缀是否为回文,两次字符串Hash可以解决。
时间复杂度 预处理O(n) + 每次询问O(1) = O(n)。
此题O(n^2)的判断方法也可以过。
有兴趣可以去试试原题,Codeforces 7D。
C要 算是思维强度比较很小的题了,可以算作模拟题了。
时间复杂度 = O(n) 的dfs预处理 + O(n)的dfs查找 = O(n)。
首先你要知道 以节点i为根的树上的节点数为 dp[i] = sigma(dp[son_j ]) + 1;son_j表示 i 的第 j 的子节点。
D记 就算不知道定理也应该会用Java写啊。。。
(a + b) % m = (a%m + b%m) %m;
(a * b) % m = ( (a%m) * (b%m) ) %m;
对于某个数S,假设一共有N位,每位分别是Ai。
那么S%m = sigma( ( Ai*10^(n-i) )%m ) %m;
其中10^x 又可以按上述定理展开,时间复杂度O(N)。
E得 最小生成树
根据算法定义,现将边按权值升序排序,依次加入途中,当加入某条边时整张图联通,那么显然最后加入的那条边就是答案啊,时间复杂度O(n*log(n) )。
如果看不出这个,也可以二分答案然后并查集或者BFS去验证啊,O(log(MAX) * n)。
F吃 现按输入的 Pi 排序,那么排序后的第一个人应该选较小的,然后第 i 个要在 大于 Key_i-1 的 A,B中选一个较小的作为Key_i。
如果每个人都有的选,那肯定就是Yes,否则就是No。
E 药 本意是签到题,其实真的是签到题,有序链表的增删,不多说了。