#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#define debug(a) cout << #a <<" = "<< a << endl;//#define x first//#define y second
#define LD long double
using namespace std;
typedef long long ll;constint N =12, M =1<< N, K =110;int n, m;
vector<int> state;
vector<int> head[M];int cnt[M];
ll f[N][K][M];boolcheck(int state){for(int i =0; i < n; i ++)if((state >> i &1)&&(state >>(i +1)&1))returnfalse;returntrue;}intcount(int state){int cnt =0;for(int i =0; i < n; i ++)cnt +=(state >> i &1);return cnt;}intmain(){cin >> n >> m;for(int i =0; i <(1<< n); i ++)if(check(i)){state.push_back(i);cnt[i]=count(i);}for(int i =0; i < state.size(); i ++)for(int j =0; j < state.size(); j ++){int a = state[i], b = state[j];if((a & b)==0&&check(a | b))// 不要寫成head[i].push_back(j);}f[0][0][0]=1;for(int i =1; i <= n +1; i ++)for(int j =0; j <= m; j ++)for(int a =0; a < state.size(); a ++)for(int b : head[a]){int c = cnt[state[a]];if(j >= c)f[i][j][a]+= f[i -1][j - c][b];}cout << f[n +1][m][0]<< endl;return0;}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#define debug(a) cout << #a <<" = "<< a << endl;//#define x first//#define y second
#define LD long double
using namespace std;
typedef long long ll;constint N =14, M =1<<12, mod =1e8;int n, m;int g[N];
vector<int> state;
vector<int> head[M];int f[N][M];boolcheck(int state){for(int i =0; i < m; i ++)if((state >> i &1)&&(state >> i +1&1))returnfalse;returntrue;}intmain(){cin >> n >> m;for(int i =1; i <= n; i ++)for(int j =0; j < m; j ++){int t;cin >> t;// g[i] += !t << j;g[i]+=!t *(1<< j);}for(int i =0; i <1<< m; i ++)// 注意m列,不是n列if(check(i))state.push_back(i);for(int i =0; i < state.size(); i ++)for(int j =0; j < state.size(); j ++)if(!(state[i]& state[j]))head[i].push_back(j);f[0][0]=1;for(int i =1; i <= n +1; i ++)// 到n + 1for(int j =0; j < state.size(); j ++)if(!(g[i]& state[j])){for(int k : head[j])f[i][j]=(f[i][j]+ f[i -1][k])% mod;}cout << f[n +1][0]<< endl;return0;}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#define debug(a) cout << #a <<" = "<< a << endl;//#define x first//#define y second
#define LD long double
using namespace std;
typedef long long ll;constint N =11, M =1<<10;int n, m;int g[110];int f[2][M][M];// 滾動數組int cnt[M];
vector<int> state;boolcheck(int state){for(int i =0; i < m; i ++)if((state >> i &1)&&((state >> i +1&1)||(state >> i +2&1)))returnfalse;returntrue;}intcount(int state){int cnt =0;for(int i =0; i < m; i ++)cnt += state >> i &1;return cnt;}intmain(){cin >> n >> m;for(int i =1; i <= n; i ++)for(int j =0; j < m; j ++){char c;cin >> c;g[i]+=(c =='H')*(1<< j);}for(int i =0; i <(1<< m); i ++)if(check(i)){state.push_back(i);cnt[i]=count(i);}for(int i =1; i <= n +2; i ++)// 特殊技巧for(int j =0; j < state.size(); j ++)for(int k =0; k < state.size(); k ++)for(int u =0; u < state.size(); u ++){int a = state[j], b = state[k], c = state[u];if(g[i -1]& a | g[i]& b)continue;if(a & b | a & c | b & c)continue;f[i &1][j][k]=max(f[i &1][j][k], f[i -1&1][u][j]+ cnt[b]);// 注意最后加上的是cnt[b]而不是cnt[k]}// 不使用特殊技巧的情況// int res = 0;// for (int i = 0; i < state.size(); i ++ )// for (int j = 0; j < state.size(); j ++ )// res = max(res, f[n & 1][i][j]);cout << f[n +2&1][0][0]<< endl;// 特殊技巧return0;}
#include<iostream>#include<cstring>usingnamespace std;constint N =15, M =1<< N, K =1010;constint INF =0x3f3f3f3f;int n, m;int g[N][N];int f[M][K];int ne[M];voidinit(){cin >> n >> m;// 圖的初始化memset(g,0x3f,sizeof g);for(int i =0; i < n;++ i) g[i][i]=0;while(m --){int a, b, c;cin >> a >> b >> c;a --, b --;// 狀態壓縮dp,所以編號從0開始g[a][b]= g[b][a]=min(g[a][b], c);}for(int st =1; st <1<< n;++ st)// 預處理所有狀態能夠擴展一層后得到的最大的下一層狀態for(int i =0; i < n;++ i)if(st >> i &1)for(int j =0; j < n;++ j)if(g[i][j]!= INF)ne[st]|=1<< j;}intget_cost(int cur,int pre){if((ne[pre]& cur)!= cur)return-1;// 如果pre延伸不到cur直接剪枝int remain = pre ^ cur;// 待更新的方案int cost =0;// 記錄邊權總和for(int i =0; i < n;++ i)if(remain >> i &1){int t = INF;for(int j =0; j < n;++ j)if(pre >> j &1)t =min(t, g[i][j]);cost += t;}return cost;// 返回該次擴展的費用}intdp(){memset(f,0x3f,sizeof f);for(int i =0; i < n;++ i) f[1<< i][0]=0;// 開局免費選一個起點(初始狀態)for(int cur =1, cost; cur <1<< n;++ cur)for(int pre = cur & cur -1; pre; pre = pre -1& cur)if(~(cost =get_cost(cur, pre)))for(int k =0; k < n;++ k)f[cur][k]=min(f[cur][k], f[pre][k -1]+ cost * k);int res = INF;for(int k =0; k < n;++ k) res =min(res, f[(1<< n)-1][k]);return res;}intmain(){init();cout <<dp()<< endl;return0;}