ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C. 连锁商店(状压dp)

2022-05-01 12:32:06  阅读:143  来源: 互联网

标签:红包 连锁商店 int 状压 60 景点 include dp


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 }

 

标签:红包,连锁商店,int,状压,60,景点,include,dp
来源: https://www.cnblogs.com/empty-y/p/16212555.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有