虽然设定里n是到40可是很明显40是带不动的
初步估计40!
求最短路径又很明显不是图论类的于是想到
贪心 dp bfs
尽管老师说搜索是可以的然而我是个搜索废
滚去写dp
一开始按大白上面的那道题的思路走的 感觉比较不顺手
可自己也码不动(太弱啦
考虑为什么不在自己的状态内进行转移(可是还是不会打
于是很怂逼去看了题解
嗯这就是我要的(滑板鞋)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
int w[30][30];
int len[30];
int s[1100000][20];
int main(){
freopen ("shou.in","r",stdin);
freopen ("shou.out","w",stdout);
int n;
scanf ("%d",&n);
int x;
//初始化 毕竟后面求最小值
memset(w,0x3f,sizeof(w));
memset(s,0x3f,sizeof(s));
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j){
scanf("%d",&x);
if (x) w[i][j]=x;
}
s[1][1]=0;
x=(1<<n)-1;//最终状态
for (int i=3;i<=x;i+=2)//枚举状态
for (int v=1;v<=n;++v){
if (i&(1<<v-1)){
for (int j=2;j<=n;++j)//枚举两个状态中的点
if (v!=j&&(i&(1<<j-1))){
int k=i&(~(1<<j-1));
//在后者还未被访问的情况下转移
s[i][j]=min(s[i][j],s[k][v]+w[v][j]);
}
}
}
int ans=100000000;
for (int i=1;i<=n;++i) ans=min(ans,s[x][i]+w[i][1]);
//走完全程回到起点
if (ans==100000000) cout<<-1;
else cout<<ans;
return 0;
}
这类题目一开始看到肯定会走弯路
估计抓破头皮也只能勉强打个疯狂优化的爆搜
所以还是要多锻炼思维啊少年
很多题目的最优解法往往是和题意不怎么直接相关的qwq