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

 

转载于:https://www.cnblogs.com/137shoebills/p/8675598.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值