CF#321-D - Kefa and Dishes-状压DP+bitmasks
来源:互联网 发布:港口历年数据 编辑:程序博客网 时间:2024/06/06 02:38
http://codeforces.com/contest/580/problem/D
题意
给出n个菜,要选出m个
每个菜有一个权值aa[i]
另有k个额外的条例
条例格式 X Y C: 如果先吃第X个菜,马上接着吃Y个菜,会得到额外的权值C
求n个菜选m个的条件下,可以得到的最大权值
思路:
由于n=18,所以我们可以用一个数的二进制位,来表示有没选第i道菜,也就是用一个数来表示当前 选择的菜的状态
i从0表示一个不选 到 i=2^n-1 表示所有菜都选了
dp[i][j] 表示 在状态i情况下,以第j个菜为最后一个菜的情况下 得到的最大权值;
由于只有18个菜,我们可以遍历2^18次方种情况,每一个数换算成二进制,如果第i位 为0表示不选,1表示选该第i个菜
伪代码:
for (i=0; i< 2^18;i++){把i转为二进制,计算1个个数 (表示选了多少道菜)如果个数>m,continue; 因为只需要选m个,超过了就不用理了如果个数==m,则更新一下答案。个数小于m的时候,说明还需要继续选菜:枚举n种情况,以每一种菜为最后一个菜for(j=0;j<17;j++){if(dp[i][j]==-1) 表示 当前状态 根本没选j,所以不存在以j为最后一菜的情况 ;continue;i状态下,j位最后一菜的情况下,菜数不够m,现在我们要再选一道菜,也是遍历每一道菜for (k=0;k<n;k++){if (i&(1<<k)) //如果为真,i状态的二进制的第k个位为1,表示第k个菜已经选过了continue; //下面是 第k个菜没选过的情况// i|(1<<k) 表示把第k个菜选上的状态(把i的二进制的第k位置为一)dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+map[j][k]+aa[k]); //更新状态 //dp[i][j]+map[j][k]+aa[k] 表示i状态下,以j结尾的情况,再选了第k菜作为结尾得到的权值} }}
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <queue> #include <set>#include <vector>using namespace std;__int64 map[19][19];__int64 max(__int64 a,__int64 b){return a>b?a:b;}__int64 n,m,k;__int64 aa[20];__int64 dp[262144+5][18+2];int main(){ __int64 n,i,j,k ; scanf("%I64d%I64d%I64d",&n,&m,&k);__int64 a,b,c; for (i=0;i<n;i++){scanf("%I64d",&aa[i]);}for (i=0;i<k;i++){scanf("%I64d%I64d%I64d",&a,&b,&c);map[a-1][b-1]=c; }memset(dp,-1,sizeof(dp));__int64 cun=(__int64)pow(2.0,n);__int64 tmp;__int64 ans=0;for (i=0;i<n;i++){dp[1<<i][i]=aa[i];} for (i=0;i<cun;i++){tmp=i;__int64 cou=0;while(tmp){if (tmp&1)cou++;tmp=tmp>>1; }__int64 flag=0;if (cou==m) flag=1;if (cou>m) continue;for (j=0;j<n;j++){if (dp[i][j]==-1)//如果该状态不包含第j个dishcontinue;if (flag) //如果当前状态已经够m个dish,ans=max(ans,dp[i][j]);for (k=0;k<n;k++){if (i&(1<<k)) //如果第k个菜已经选了continue;// i|(1<<k) 表示把第k个dish选上的状态dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+map[j][k]+aa[k]);}}}printf("%I64d\n",ans); return 0;}
0 0
- CF#321-D - Kefa and Dishes-状压DP+bitmasks
- CF D. Kefa and Dishes (状态转移dp)
- codeforces 321# D. Kefa and Dishes (状态压缩DP)
- codeforces 580 D.Kefa and Dishes(状压DP)
- codeforces 580 D. Kefa and Dishes (状压dp)
- codeforces 580D. Kefa and Dishes(状压dp)
- Codeforces 580D Kefa and Dishes【状压dp】
- codeforces 580D Kefa and Dishes (状压dp)
- CodeForces 580D.Kefa and Dishes(状压DP)
- CodeForces 580 D.Kefa and Dishes(状压DP)
- CodeForces 580D (状压DP) Kefa and Dishes
- codeforces 580D. Kefa and Dishes dp
- CF 580D Kefa and Dishes(简单状压dp)
- Codeforces Round #321 Kefa and Dishes(状压DP)
- Codeforces Round#321 Kefa and Dishes(状压DP)
- 状压dp Codeforces580D Kefa and Dishes
- CodeForces 580D Kefa and Dishes(DP)
- codeforces 580D Kefa and Dishes【状态压缩+dp】
- ZOJ-3894-Chessgame【区间dp】
- C++primer第五版笔记-第七章类
- 笔记:学习 Android -Services 基础
- 算法中可以使用不等式变换避免溢出,leetcode:Sqrt(x) ,BigInteger处理溢出
- 直到谷歌重组,我才明白谷歌和百度不止隔着一个太平洋
- CF#321-D - Kefa and Dishes-状压DP+bitmasks
- Android开发之基础-------------Get请求和Post请求
- hdu 1241 Oil Deposits(dfs)
- 从酷狗的网络红歌说起
- Springmvc Hello World
- Insert Interval
- JAVA实现判断树的子结构及树的镜像问题(《剑指offer》)
- ListView与ViewPager组合(二)
- 条款25:全特化和偏特化