一个显然的结论是最终树的形态必然是一条链。具体证明只要考虑选定树上的某一条链,然后把其他部分全部接在它后面,这样答案一定不会变劣。

那么,一开始的想法是考虑每一位的最后出现位置,但这并不容易实现。注意到最终序列是单调递减的。我们在统计答案之前,把公共位先统计掉,即始终都是1的位。这样,剩下的位的最终结果都是0。这样,我们就避免了在统计时忽略某些数。那么,我们记dp[i]表示当前的结果为i的最小费用。我们在转移时枚举下一个数字是什么。这里无需担心数字的重复放置,因为它并不能让当前的数字发生变化。那么,我们就有如下第5档部分分。

memset(dp,0x3f,sizeof dp);
for (int i = 1 ; i <= n ; ++ i)
dp[arr[i]] = arr[i];
for (int i = MAX - 1 ; i >= 1 ; -- i)
for (int j = 1 ; j <= n ; ++ j)
if ((i & arr[j]) < i)
dp[i&arr[j]] = min(dp[i&arr[j]],dp[i] + (i&arr[j]));

注意到这里需要(i&arr[j])<i,即\(C_uarr[j] \bigcap i \neq \emptyset\)。那么,我们把所有\(C_uarr[j]\)的子集存下来,然后转移时枚举子集就做到dp时复杂度与n无关了。

时间复杂度大概是:\(O(a^{log_23})\)。

看起来很爆炸,但是非常不满。

#include <bits/stdc++.h>
#define rint register int
using namespace std;
typedef long long ll;
const int N = 200010, MAX = 1 << 18;
int arr[N],n,avail[MAX + 5],com;
ll dp[MAX + 5];
#define rev(x) ((x) ^ (MAX - 1))
int main() {
com = MAX - 1;
scanf("%d",&n);
for (rint i = 1 ; i <= n ; ++ i)
scanf("%d",&arr[i]), com &= arr[i];
for (rint i = 1 ; i <= n ; ++ i)
arr[i] ^= com;
for (rint i = 1 ; i <= n ; ++ i) {
if (avail[rev(arr[i])]) continue;
for (rint j = rev(arr[i]) ; j ; j = (j-1) & rev(arr[i]))
avail[j] = 1;
}
memset(dp,0x3f,sizeof dp);
for (rint i = 1 ; i <= n ; ++ i) dp[arr[i]] = arr[i];
for (rint i = MAX-1 ; i >= 1 ; -- i) if (dp[i] < dp[0]) {
for (rint j = i ; j ; j = (j-1) & i) if (avail[j])
dp[i^j] = min(dp[i^j],dp[i] + (0ll^i^j));
}
printf("%lld\n",1ll * com * n + dp[0]);
return 0;
}

小结:抓住题目的特殊性质是优化的关键。

【做题】uoj#370滑稽树上滑稽果——巧妙dp的更多相关文章

  1. U68464 滑稽树上滑稽果(guo)

    U68464 滑稽树上滑稽果(guo) 题目描述 小小迪有 n 个约会对象,每个对象有一个约会时长 p[i],小小迪 想尽可能多的去完成他的约会(假设小小迪可以瞬移),每个对象还有 一个忍耐时间 q[ ...

  2. uoj#370【UR #17】滑稽树上滑稽果

    题目 低智选手果然刷不动uoj 首先考虑一下构造一棵树显然是骗你玩的,按位与这个东西越做越小,挂到链的最下面显然不会劣于挂到之前的某一个点下面,所以我们只需要求一个排列使得答案最小就好了 设\(A=\ ...

  3. UOJ#370. 【UR #17】滑稽树上滑稽果 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ370.html 题解 首先易知答案肯定是一条链,因为挂在链的最下面肯定比挂在其他节点上赚. 问题被转化成了从一个集合中不断 ...

  4. UOJ#370. 【UR #17】滑稽树上滑稽果

    $n \leq 1e5$个点,每个点有个权值$a_i \leq 2e5$.现将点连成树,每个点$i$的链接代价为$a_i \ \ and \ \ i父亲的代价$,这里的$and$是二进制按位与,求最小 ...

  5. UOJ370 滑稽树上滑稽果 【状压DP】

    题目分析: 答案肯定是链,否则可以把枝干放到主干. 去除一直存在的位,这样0位占满时就会结束. 用$f[S]$表示0位填埋情况,每次转移是它的一个子集,我们考虑可否转移. 再用$g[S]$存储转移是否 ...

  6. 吉首大学2019年程序设计竞赛(重现赛)I 滑稽树上滑稽果 (莫队+逆元打表)

    链接:https://ac.nowcoder.com/acm/contest/992/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K  ...

  7. 吉首大学校赛 I 滑稽树上滑稽果 (Lucas + 莫队)

    链接:https://ac.nowcoder.com/acm/contest/925/I来源:牛客网 题目描述 n个不同的滑稽果中,每个滑稽果可取可不取,从所有方案数中选取一种,求选取的方案中滑稽果个 ...

  8. A. 【UR #17】滑稽树上滑稽果

    题解: 首先很显然的是这是一条链(特殊数据说是链是故意让人迷茫的??) 然后 自己就开始yy 觉得每一次是加入一个使得当前值最小的数 然而这tm又是特殊数据?? 那就写一波发现是错的 考虑一下特殊数据 ...

  9. 【做题】arc078_f-Mole and Abandoned Mine——状压dp

    题意:给出一个\(n\)个结点的联通无向图,每条边都有边权.令删去一条边的费用为这条边的边权.求最小的费用以删去某些边使得结点\(1\)至结点\(n\)有且只有一条路径. \(n \leq 15\) ...

随机推荐

  1. c#之根据出生日期获得星座信息

    星座定义如下: 代码如下: public enum Constellation { Aquarius = , // 水瓶座 1.20 - 2.18 Pisces = , // 双鱼座 2.19 - 3 ...

  2. Sql Server参数化查询之where in和like实现详解 [转]

    文章导读 拼SQL实现where in查询 使用CHARINDEX或like实现where in 参数化 使用exec动态执行SQl实现where in 参数化 为每一个参数生成一个参数实现where ...

  3. Sitecore CMS中更改项目的模板

    如何在Sitecore CMS中创建项目后更改项目的模板. 在创建项目时选择了错误的模板,或者创建了新模板并将现有项目更新为新模板时,这非常有用.   警告! 更改模板时要小心.如果原始模板具有不在新 ...

  4. C# SQLite 数据库操作

    C# SQLite 数据库操作学习 运行环境:Window7 64bit,.NetFramework4.61,C# 7.0 参考: SQLite 官网 SQL As Understood By SQL ...

  5. 20155228 2017-5-10 课堂测试:Arrays和String单元测试

    20155228 2017-5-10 课堂测试:Arrays和String单元测试 题目和要求 在IDEA中以TDD的方式对String类和Arrays类进行学习 测试相关方法的正常,错误和边界情况 ...

  6. Mysql Federated For Windows

    [1]windows环境下打开federated (1)关闭.命令:mysql> net stop mysql (2)添加federated字段.在my.ini文件中添加一个字段,注意位于[my ...

  7. Hive中变量的使用

    1.Hive配置属性 (1)命令行方式 Hive配置属性存储于 hiveconf 命名空间中,该命名空间中的属性是可读写的.在查询语句中插入 '${hiveconf:变量名}',就可以通过 hive ...

  8. 调用微信JS-SDK配置签名

    前后端进行分开开发: 1:后端实现获取 +++接口凭证:access_token (公众号的全局唯一接口调用凭据) ** GET 获取:https://api.weixin.qq.com/cgi-bi ...

  9. flask模板的基本用法(定界符、模板语法、渲染模板),模板辅助工具(上下文、全局对象、过滤器、测试器、模板环境对象)

    flask模板 在动态web程序中,视图函数返回的HTML数据往往需要根据相应的变量(比如查询参数)动态生成. 当HTML代码保存到单独的文件中时,我们没法再使用字符串格式化或拼接字符串的当时在HTM ...

  10. C# 设置按钮快捷键

    参考自:http://www.csharpwin.com/csharpspace/3932r8132.shtml 一.C# button快捷键之第一种:Alt + *(按钮快捷键) 在Button按钮 ...