C. 连锁商店
time limit per test

1 second

memory limit per test

512 megabytes

input

standard input

output

standard output

比特山是一个旅游胜地,它一共有 n个景点,按照海拔高度从低到高依次编号为 1到 n。为了更好地帮助游客们欣赏这里的风景,人们在上面搭建了 m 条缆车路线。

每条缆车路线只可能把游客们从某个海拔较低的景点运送到另一个海拔较高的景点。

在每个景点都有一家纪念品连锁商店,其中第 i 个景点的商店隶属第 ci 号公司,两家连锁店 (i,j) 隶属同一公司当且仅当 ci=cj。每家公司都有新客优惠活动,其中第i家公司对于新客的优惠红包为 wi 元,

一旦领取了隶属该公司的某家连锁店的一份红包,就不能再领取该公司所有分店的红包。

你正在 1号景点,你将会搭乘缆车去往各个景点,每到一个景点,你都可以领取该景点的连锁商店的新客优惠红包(包括 1 号景点)。当然,同一家公司的红包最多只能领一次。

请写一个程序,对于每个可能的终点 k,找到一条从 1 号景点出发到达 k 号景点的游览路线,使得可以领取到总金额最多的优惠红包。

Example
input

 
5 5
1 2 2 3 4
1 4 5 9 3
1 2
2 3
3 5
1 4
4 5
output

 
1
5
5
6
15

这道题比较关键的就是隶属关系,当我们选则在同一集合内的任意一个之后,其他的红包则不能领取

所以依据这种关系我们可以将这道题看作在不同状态下选择某一个红包,不断在各个状态下更新当前状态下能够获取的红包最大值

建立状压dp,dp[i][j]表示在站点 i 时处于状态 j 下能够获得的最大红包值

这样建立的dp虽然也能运行,但是2^36次着实有点大,容易TLE,所以我们可以对原始的关系进行优化

因为线路在选择时假设我们可以1->2->3->4,和1->4,那我们肯定选择1->2->3->4,这种情况下我们能获得红包的可能是最大的

所以在建图时对此进行优化

 1 # include<iostream>
2 # include<algorithm>
3 # include<cstring>
4 # include<vector>
5 # include<map>
6 # define int long long
7 # define endl "\n"
8 using namespace std;
9 const int N = 2e5 + 10;
10 int a[N], b[N];
11 int ne[N];
12 vector<int> p[60], go[60], zt[60];
13 map<int, int> dp[60];
14 int g[60][60];/*初次存图*/
15 int ans[60];
16 void solve() {
17 int n, m;
18 cin >> n >> m;
19 for (int i = 1; i <= n; ++i) {
20 cin >> a[i];
21 p[a[i]].push_back(i);/*
22 存储隶属关系
23 */
24 }
25 for (int i = 1; i <= n; ++i) {
26 cin >> b[i];/*每个点的红包值*/
27 }
28 for (int i = 1; i <= m; ++i) {
29 int x, y;
30 cin >> x >> y;
31 g[x][y] = 1;/*建图*/
32 }
33 for (int i = 1; i <= n; ++i)
34 for (int j = i + 1; j <= n; ++j)
35 for (int k = i + 1; k <= j; ++k)
36 if (g[i][j] == 1 && g[i][k] == 1 && g[k][j] == 1)
37 g[i][j] = 0;/*优化建图*/
38
39 for (int i = 1; i <= n; ++i)
40 for (int j = i + 1; j <= n; ++j)
41 if (g[i][j]) go[j].push_back(i);/*记录每个点的上一个点*/
42 dp[1][(int)1 << a[1]] = b[a[1]];
43 ans[1] = b[a[1]];
44 zt[1].push_back((int)1 << a[1]);
45
46 for (int i = 2; i <= n; ++i) {
47 int bit = a[i];
48 for (int res : go[i])/*枚举当前节点可以从上一个节点的哪个状态转移来*/
49 for (int s : zt[res]) {/*枚举上一个节点的所有状态*/
50 if (s & (int)1 << bit) {/*如果上一个节点已经路过了*/
51 if (!dp[i].count(s)) {/*当前节点是否存储过当前状态*/
52 dp[i][s] = dp[res][s];
53 zt[i].push_back(s);/*没存储过就存这个状态*/
54 }
55 dp[i][s] = max(dp[i][s], dp[res][s]);/*迭代*/
56 ans[i] = max(ans[i], dp[i][s]);/*更新到达当前节点的最大红包值*/
57 }
58 else{/*若没经过上一个点*/
59 int now = s|(int)1<<bit;/*现在的状态*/
60 if(!dp[i].count(now)){
61 zt[i].push_back(now);
62 }
63 dp[i][now] = max(dp[i][now],dp[res][s]+b[a[i]]);/*如果没经过上一个点那么当前节点就会多一个红包*/
64 ans[i] = max(ans[i],dp[i][now]);
65 }
66 }
67 }
68 for(int i = 1;i <= n;++i) cout<<ans[i]<<endl;
69
70 }
71 int tt;
72 signed main() {
73 ios::sync_with_stdio(false);
74 cin.tie(nullptr);
75 cout.tie(nullptr);
76 tt = 1;
77 while (tt--) {
78 solve();
79 }
80
81
82 return 0;
83 }

C. 连锁商店(状压dp)的更多相关文章

  1. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  2. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  3. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  4. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  5. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  6. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

  7. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

  8. 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP

    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...

  9. 【BZOJ1725】[Usaco2006 Nov]Corn Fields牧场的安排 状压DP

    [BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排 Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M< ...

随机推荐

  1. mybatisplus-ActiveRecord 模式

    ActiveRecord 模式 直接调用Model对象来进行增删改查. 实体类只需继承 Model 类即可进行强大的 CRUD 操作 需要项目中已注入对应实体的BaseMapper 实体类User 点 ...

  2. Python自学教程12-类和对象怎么用

    Python是一门现代化的编程语言,也是一门面向对象的编程语言. 现代编程语言几乎都支持面向对象编程,面向对象编程是最有效的软件编写方法之一.你可以用类和对象来表示现实当中的任何的事物和行为. 编写类 ...

  3. dotnet 设计规范 · 数组定义

    ✓ 建议在公开的 API 使用集合而不是数组.集合可以提供更多的信息. X 不建议设置数组类型的字段为只读.虽然用户不能修改字段,但是可以修改字段里面的元素.如果需要一个只读的集合,建议定义为只读集合 ...

  4. RT-Thread Studio增加软件包操作

    RT-Thread Studio增加软件包操作 1. 在本地中完成如下操作 打开RTthread Studio的安装目录 在当前目录下找到env的目录 在env的目录下找到要添加软件包的分类文件夹 本 ...

  5. KingbaseES R6 集群备库网卡down测试案例

    数据库版本: test=# select version(); version ------------------------------------------------------------ ...

  6. Centos_yum使用

    安装应用 yum install -y xxx -y 表示自动yes 卸载应用 yum -y remove xxx -y 表示自动yes 查看已安装的应用 yum list installed

  7. python3实现:进程遇Error定时重启

    import os import time # 停止HFish def stopHFish(): # while True: try: # 找到HFish进程号 HFish_id = int(os.p ...

  8. Solutions:Elastic SIEM - 适用于家庭和企业的安全防护 ( 二)

  9. 使用prometheus + granafa 监控mysql主从

    若主从同步数据库未同步默认的mysql表,则也需要在从库上创建mysql用户mysqld_exporter用来收集监控数据 mysqld_exporter安装部署 这里采取的是mysqld_expor ...

  10. MongoDB 副本集的用户和权限一般操作步骤

    步骤总结: 在主节点上添加超管用户,副本集会自动同步 按照仲裁者.副本节点.主节点的先后顺序关闭所有节点服务 创建副本集认证的key文件,复制到每个服务所在目录 修改每个服务的配置文件,增加参数 启动 ...