题意:给定n个菜,每个菜都有一个价值,给定k个规则,每个规则描述吃菜的顺序:i j w,按照先吃i接着吃j,可以多增加w的价值。问如果吃m个菜,最大价值是多大。其中n<=18

思路:一看n这么小,除了暴力之外就得想想状态压缩dp了。因为每种菜正好两种状态(吃过与没吃过),正好可以使用二进制来表示每种状态,那么一共有(1<<n)位种可能,即从状态(000...0)到状态(111...1),所以定义状态dp[s][i],表示状态为s时,并且最后吃第i种菜的时候的最大值。那么转移方程就是

dp[s|(1<<j)] = max(dp[s|(1<<j)], dp[s][i] + ary[i] + ad[i][j];

其中ary表示每种菜的价值,ad[i][j]表示先吃i再吃j的价值。注意状态方程转移的条件:第i位已经选择过,第j位没有选择过。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ( << ) + ;
long long dp[maxn][];
long long ary[];
long long ad[][];
int main()
{
int n, m, k, u, v, w;
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i < n; i++) cin >> ary[i];
for (int i = ; i < k; i++)
{
scanf("%d%d%d", &u, &v, &w);
u--; v--;
ad[u][v] = w;
}
for (int i = ; i < n; i++)
dp[<<i][i] = ary[i];
long long ans = ;
int tot = << n;
for (int s = ; s < tot; s++)
{
int cnt = ;
for (int i = ; i < n; i++)
{
if ((s & ( << i)) != )
{
cnt++;
for (int j = ; j < n; j++)
{
if ((s & (<<j)) == ) //be careful the priority of operator
{
int ss = s | ( << j);//the next state
dp[ss][j] = max(dp[ss][j], dp[s][i] + ary[j] + ad[i][j]); } } }
}
if (cnt == m)
{
for (int i = ; i < n; i++)
if ((s & (<<i)) != ) ans = max(ans, dp[s][i]);
}
}
cout << ans << endl; return ;
}

codeforces 580D Kefa and Dishes(状压dp)的更多相关文章

  1. Codeforces Round #321 (Div. 2) D. Kefa and Dishes 状压dp

    题目链接: 题目 D. Kefa and Dishes time limit per test:2 seconds memory limit per test:256 megabytes 问题描述 W ...

  2. Codeforces ----- Kefa and Dishes [状压dp]

    题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...

  3. Codeforces 580D Kefa and Dishes(状态压缩DP)

    题目链接:http://codeforces.com/problemset/problem/580/D 题目大意:有n盘菜每个菜都有一个满意度,k个规则,每个规则由x y c组成,表示如果再y之前吃x ...

  4. CF580D Kefa and Dishes 状压dp

    When Kefa came to the restaurant and sat at a table, the waiter immediately brought him the menu. Th ...

  5. dp + 状态压缩 - Codeforces 580D Kefa and Dishes

    Kefa and Dishes Problem's Link Mean: 菜单上有n道菜,需要点m道.每道菜的美味值为ai. 有k个规则,每个规则:在吃完第xi道菜后接着吃yi可以多获得vi的美味值. ...

  6. codeforces 580D. Kefa and Dishes

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  7. Codeforces Round #363 LRU(概率 状压DP)

    状压DP: 先不考虑数量k, dp[i]表示状态为i的概率,状态转移方程为dp[i | (1 << j)] += dp[i],最后考虑k, 状态表示中1的数量为k的表示可行解. #incl ...

  8. codeforces 8C. Looking for Order 状压dp

    题目链接 给n个物品的坐标, 和一个包裹的位置, 包裹不能移动. 每次最多可以拿两个物品, 然后将它们放到包里, 求将所有物品放到包里所需走的最小路程. 直接状压dp就好了. #include < ...

  9. Codeforces 429C Guess the Tree(状压DP+贪心)

    吐槽:这道题真心坑...做了一整天,我太蒻了... 题意 构造一棵 $ n $ 个节点的树,要求满足以下条件: 每个非叶子节点至少包含2个儿子: 以节点 $ i $ 为根的子树中必须包含 $ c_i ...

随机推荐

  1. 使用HttpURLConnection向服务器发送post和get请求

    一.使用HttpURLConnection向服务器发送get请求 1.向服务器发送get请求 @Test publicvoid sendSms() throws Exception{ String m ...

  2. bzoj1570

    购买的机票限制和数据范围很容易想到是网络流不难想到每个城市按时刻拆点,这也是一个经典模型由于时间不会太大,我们穷举时间,不断在残留网络上建图,跑最大流直至总流量为k即可 ; type node=rec ...

  3. android layout 属性大全

    第一类:属性值为true可false android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android:la ...

  4. JAVA 数组常用技巧

    1.  在Java中输出一个数组(Print an array in Java) int[] intArray = { 1, 2, 3, 4, 5 }; String intArrayString = ...

  5. (转载)Linux一句话精彩

    (转载)http://bjsfly.blog.163.com/blog/static/161276642007845228371/ 0001[url=111]111[/url] [ 本帖最后由 bjc ...

  6. 计算几何(凸包模板):HDU 1392 Surround the Trees

    There are a lot of trees in an area. A peasant wants to buy a rope to surround all these trees. So a ...

  7. 切换Oracle数据库实例

    如果多个实例,需要切换可以采用以下命令: export ORACLE_SID=SID

  8. bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)

    1513: [POI2006]Tet-Tetris 3D Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 540  Solved: 175[Submit ...

  9. [ZETCODE]wxWidgets教程二:辅助类

    本教程原文链接:http://zetcode.com/gui/wxwidgets/helperclasses/ 翻译:瓶哥 日期:2013年11月27日星期三 邮箱:414236069@qq.com ...

  10. cpp