LOJ P3959 宝藏 状压dp noip

Posted 鲸头鹳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LOJ P3959 宝藏 状压dp noip相关的知识,希望对你有一定的参考价值。

https://www.luogu.org/problemnew/show/P3959

考场上我怎么想不出来这么写的,状压白学了。

直接按层次存因为如果某个点在前面存过了则肯定结果更优所以不用在意各点的层次只用在意最深的点的层次。

调的时候因为e最开始初始化太大了溢出了好几次mdzz。

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 using namespace std;
 8 const int maxn=600010;
 9 int n,m;
10 int e[15][15]={};
11 int f[15][4400]={};
12 int yu[4400]={},v[15]={},id[15]={},tot;
13 int p[4400]={},qun[4400]={};
14 int main(){
15     memset(e,1,sizeof(e));
16     memset(f,63,sizeof(f));
17     //cout<<e[0][0]<<endl;
18     scanf("%d%d",&n,&m);
19     int x,y,val,mx=(1<<n),mnum=f[0][0];
20     for(int i=1;i<=m;i++){
21         scanf("%d%d%d",&x,&y,&val);
22         e[x][y]=min(val,e[x][y]);e[y][x]=e[x][y];
23     }
24     for(int i=1;i<=n;i++)yu[1<<(i-1)]=i;
25     for(int i=1;i<=n;i++)f[1][1<<(i-1)]=0;
26     for(int i=1;i<n;i++){
27         for(int j=1;j<mx;j++){
28             tot=0;
29             for(int w=1;w<=n;w++){
30                 if((1<<(w-1))&j)continue;
31                 v[++tot]=mnum;id[tot]=1<<(w-1);
32                 for(int z=j;z;z-=(z&-z))
33                     v[tot]=min(v[tot],e[yu[z&-z]][w]*i);
34             }
35             int mn=(1<<tot);
36             for(int w=1;w<mn;w++){
37                 p[w]=p[w-(w&-w)]+v[yu[w&-w]];
38                 qun[w]=qun[w-(w&-w)]|id[yu[w&-w]];
39                 f[i+1][j|qun[w]]=min(f[i+1][j|qun[w]],f[i][j]+p[w]);
40             }
41         }
42     }
43     int ans=mnum;
44     for(int i=1;i<=n+1;i++)ans=min(ans,f[i][mx-1]);
45     printf("%d\n",ans);
46     return 0;
47 }
View Code

 

以上是关于LOJ P3959 宝藏 状压dp noip的主要内容,如果未能解决你的问题,请参考以下文章

题解P3959 宝藏 - 状压dp / dfs剪枝

NOIP 2017 宝藏 (状压dp+贪心)

[luogu3959 noip2017] 宝藏 (状压dp)

Luogu P3959 宝藏

P3959 [NOIP2017 提高组] 宝藏

NOIP2017 - 宝藏