CF580D Kefa and Dishes [洛谷]
一、题目大意
进入了一家餐厅,这家餐厅中有个菜(),对第个菜的满意度为(),并且对于这个菜有个规则,如果在吃完第个菜之后吃了第个菜(保证不相等),那么会额外获得()的满意度。要吃道任意的菜(),但是他希望自己吃菜的顺序得到的满意度最大,请你帮帮吧!
输入第一行是三个数:
第二行是个数,第个数表示对第道菜的满意度为
第三行到第行每行有个数:,表示如果在吃完第道菜之后立刻吃了第道菜,则会额外获得的满意度
输入#1
2 2 1
1 1
2 1 1
输出#1
3
输入 #2
4 3 2
1 2 3 4
2 1 5
3 4 2
输出 #2
12
二、题目分析
翻译的人还好心的告诉我们要用状压。。。,其实看看数据范围也可以证明这一点,。而且"XXX"最大之流,看着就像是动态规划吧!
这题在一般状压的基础上加了一点变化:状态之间有联系,其实也是废话,状态之间没有冲突,没有关联,还用你来做题吗?
题目中说:这个菜有个规则,如果在吃完第个菜之后吃了第个菜(保证不相等),那么会额外获得 ()的满意度。
显然这是与吃菜的顺序有关的
但是再仔细考虑一下,会发现其实也是没有后效性的
因为一道菜只与它前面的那道菜有关
显然我们可以枚举要吃的菜的前面那道菜
不妨设状态表示当状态为时,最后吃的一道菜为时获得的最大满意度
-
当前状态 :
-
当前状态包含这道菜,且前序状态不包含
因为需要包含了这道菜,即的第位置必须是
前序状态不能包含这道菜,即前序状态的第位置需要是
也就是:^
可行的状态有转移方程:
^
显然当那些状态中存在个时(已经吃了道菜)取即为最后的答案
三、完整代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 20;
int a[N], c[N][N];
int K;
int n, m;
LL f[1 << N][N], ans;
//统计某个状态中数字1的数量
int count(int x) {
int res = 0;
for (int i = 0; i < 32; i++) res += x >> i & 1;
return res;
}
int main() {
cin >> n >> m >> K;
for (int i = 0; i < n; i++) { //下标从0开始
cin >> a[i];
f[1 << i][i] = a[i]; //只吃一个的初始化
}
while (K--) {
int x, y, w;
cin >> x >> y >> w;
x--, y--; //状态压缩的套路
c[x][y] = w; //记录x,y的前后关联关系
}
for (int i = 0; i < (1 << n); i++) { //枚举所有状态
for (int j = 0; j < n; j++) { //枚举每一位
if ((i & (1 << j)) == 0) continue; //不包含j的不是本次要计算的状态
for (int k = 0; k < n; k++) { //枚举前一次最后一个菜k,看看会不会获取到更大的满意度
/*
1、本轮吃下j,最后形成i这样的状态,那么上轮没有j,状态为 i^(1<<j)
2、上轮的状态是固定的,那么上轮的什么是不固定的呢?
答案:最后吃的是什么不固定!我们需要枚举所有上轮最后一个菜吃的是什么东西。
很显然,上轮最后一个菜不能是j。
如果上轮最后一个菜是k,本轮还只能吃j,则本轮的结果中必然包含k!
如果不包含k,那么k是天上掉下来的吗?这就是本题的状态之间关联关系的推导过程
由此可见,状态压缩DP的精髓在于:
状态的转移关系确定!
*/
if (j == k || (!(i & (1 << k))))continue;//相同或没吃过k不合法
//dp转移方程
f[i][j] = max(f[i][j], f[i ^ (1 << j)][k] + a[j] + c[k][j]);
}
//已经吃了m个菜就统计答案
if (m == count(i))ans = max(ans, f[i][j]);
}
}
printf("%lld\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2018-02-10 大数据统计分析平台之三、Kibana安装和使用
2018-02-10 大数据统计分析平台之一、Kafka单机搭建
2012-02-10 在Linux下配置squid[转载,待测试]
2012-02-10 内网用ssh连接linux很慢
2012-02-10 centos5.5 64位提升sata硬盘速度
2012-02-10 CentOS 64bit密码正确却无法登录系统
2012-02-10 Linux的内存释放脚本