Acwing 5729.闯关游戏 状压DP
Acwing 5729.闯关游戏 状压DP
题意:
现在进行一个闯关游戏,一共有
思路:
注意到数据范围,贪心不可行。不妨尝试状压DP。
数组第一维自然就是表示选择的状态,第二维我们要考虑如何进行划分。我们可以考虑以最后一次选择的关卡进行划分。
因此,定义
接着考虑如何转移。结合题意中的联动彩蛋,很自然的想到,我们可以去枚举倒数第二次的关卡选择,这样便可以进行状态转移。
即
最后我们只需要再枚举一遍,找出状态中恰好选取了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 20, M = 105;
const int mod = 1e9 + 7;
const int cases = 0;
LL f[1<<N][N];
int w[N],g[N][N];
void Showball(){
int n,m,k;
cin>>n>>m>>k;
for(int i=0;i<n;i++) cin>>w[i];
while(k--){
int x,y,c;
cin>>x>>y>>c;
g[x-1][y-1]=c;
}
for(int i=0;i<n;i++) f[1<<i][i]=w[i];
for(int i=0;i<1<<n;i++){
for(int j=0;j<n;j++){
if(i>>j&1){
for(int k=0;k<n;k++){
if(k!=j&&i>>k&1){
f[i][j]=max(f[i][j],f[i-(1<<j)][k]+g[k][j]+w[j]);
}
}
}
}
}
LL ans=0;
for(int i=0;i<1<<n;i++){
int cnt=0;
for(int j=0;j<n;j++){
if(i>>j&1) cnt++;
}
if(cnt==m){
for(int j=0;j<n;j++){
ans=max(ans,f[i][j]);
}
}
}
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T=1;
if(cases) cin>>T;
while(T--)
Showball();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人