狀態壓縮dp,Codeforces ----- Kefa and Dishes [狀壓dp]

 2023-10-18 阅读 32 评论 0

摘要:題目傳送門:580D ? 題目大意:給你n道菜以及每道菜一個權值,k個條件,即第y道菜在第x道后馬上吃有z的附加值,求從中取m道菜的最大權值 看到這道題,我們會想到去枚舉,但是很顯然這是會超時的,再一看數據范圍,n只有18,那么我們就可以用狀壓去做了,dp數組也還是比較好定義的,dp[i]

題目傳送門:580D

?

題目大意:給你n道菜以及每道菜一個權值,k個條件,即第y道菜在第x道后馬上吃有z的附加值,求從中取m道菜的最大權值

看到這道題,我們會想到去枚舉,但是很顯然這是會超時的,再一看數據范圍,n只有18,那么我們就可以用狀壓去做了,dp數組也還是比較好定義的,dp[i][state]表示現在吃到第i道菜狀態為state的最大權值,既然有k個限制條件我們就按每個菜去擴展,然后就是一個裸的狀壓dp了,記得要開long long

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#define in(i) (i=read())
using namespace std;
typedef long long lol;
lol read()
{lol ans=0,f=1;char i=getchar();while(i<'0'||i>'9'){if(i=='-') f=-1;i=getchar();}while(i>='0'&&i<='9'){ans=(ans<<1)+(ans<<3)+i-'0';i=getchar();}return ans*f;
}
lol dp[19][1<<18];
lol a[19],b[19][19];
lol n,m,k;
int main()
{lol ans=0;in(n);in(m);in(k);for(lol i=1;i<=n;i++) in(a[i]);for(lol i=1;i<=k;i++){lol u,v,c;in(u);in(v);in(c);b[u][v]=c;}for(lol i=1;i<=n;i++) dp[i][1<<i-1]=a[i];for(lol i=0;i<(1<<n);i++){lol cnt=0;for(lol j=1;j<=n;j++){if(i&(1<<(j-1))){cnt++;//這里的cnt是已經經過前面的if的語句,也就是說這里的cnt是看此狀態有多少位是1,也就是會吃多少道菜,所以才有了下面的if(cnt==m)這個語句for(lol k=1;k<=n;k++){if(!(i&(1<<k-1))){dp[k][i|(1<<k-1)]=max(dp[k][i|(1<<k-1)],dp[j][i]+a[k]+b[j][k]);}}}}if(cnt==m){for(lol j=1;j<=n;j++)if(i&(1<<(j-1)))//一定要記得判斷ans=max(ans,dp[j][i]);}}cout<<ans<<endl;return 0;
}

轉載于:https://www.cnblogs.com/real-l/p/8597827.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/146113.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息