最小长度电路板排列问题

来源:互联网 发布:电脑桌面记事提醒软件 编辑:程序博客网 时间:2024/04/28 08:28
85287Ronnoc10348GNU C++Accepted1284KB46ms2979B2013-07-31 01:02:09.0

题目链接http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=10348

终于过了。。。

本来是过了多校03的1003想找个排列计数问题乱搞的

结果搜到了这道题

觉得还有点意思

然后就从11点坑到了现在

还好终于过了

可以去睡了orz

还是觉得要记录下来

这货明显是个存在性搜索。。。

貌似出个结果也只是来个记录数组在update的时候更新下,没什么意思,虽然有这个略微加强版的题,但没兴趣了

check是输出当前的排列的结果

IDA是个贪心,出个大概结果

getbest是寻找当前有了一部分ch的最小可能结果(关键剪枝函数)

match数组表示这个点可能的最左差值点

那个小于t+1是核心

for(i=1;i<=m;i++)if(match[i]<t+1)L.push_back(match[i]);sort(L.begin(),L.end());int cut=1;for(i=0;i<L.size();i++)cut=max(cut,t+1+i-L[i]+1);

虽然夜已深,但是能过,就好

like AC best

PS: 昨天多校水爆了。。。orz


#include <iostream>#include <vector>#include <algorithm>#include <cstdlib>using namespace std;int ch[23];int n, m;vector<int>N[23];vector<int>B[23];int res;int check() {int local[23];int i, j;for (i = 1; i <= m; i++) local[ch[i]] = i;int ret = 1;for (i = 1; i <= n; i++) {int xmin = 23, xmax = -1;for (j = 0; j < N[i].size(); j++) xmin = min (xmin, local[N[i][j]]);for (j = 0; j < N[i].size(); j++) xmax = max (xmax, local[N[i][j]]);ret = max (ret, xmax - xmin + 1);}return ret;}int IDA (int t, int x) {ch[t] = x;int i, j, k;int did[23];for (i = 1; i <= m; i++) did[i] = 0;for (i = 1; i <= t; i++) did[ch[i]] = 1;for (j = t + 1; j <= m; j++) {int ok = 0;for (i = 0; !ok && i < B[ch[j - 1]].size(); i++) {int q = B[ch[j - 1]][i];for (k = 0; !ok && k < N[q].size(); k++) {if (!did[N[q][k]]) {ok = 1;did[N[q][k]] = 1;ch[j] = N[q][k];}}}if (!ok) {for (i = 1; i <= m; i++) {if (!did[i]) {ch[j] = i;did[i] = 1;break;}}}}return check();}int get_best (int t, int x) {ch[t] = x;int local[23];int i, j;for (i = 1; i <= m; i++) local[i] = t + 1;for (i = 1; i <= t; i++) local[ch[i]] = i;int match[23];for(i=1;i<=m;i++)match[i]=23;int ret = 1;vector<int >L;L.clear();for (i = 1; i <= n; i++) {int xmin = 23, xmax = -1;for (j = 0; j < N[i].size(); j++) xmin = min (xmin, local[N[i][j]]);for (j = 0; j < N[i].size(); j++) xmax = max (xmax, local[N[i][j]]);for (j = 0; j < N[i].size(); j++) if(local[N[i][j]]==t+1)match[N[i][j]]=min(match[N[i][j]],xmin);ret = max (ret, xmax - xmin + 1);}for(i=1;i<=m;i++)if(match[i]<t+1)L.push_back(match[i]);sort(L.begin(),L.end());int cut=1;for(i=0;i<L.size();i++)cut=max(cut,t+1+i-L[i]+1);return max(ret,cut);return ret;}bool can (int t, int x) {int i;for (i = 1; i < t; i++) if (ch[i] == x) return 0;return 1;}void dfs (int t) {if (t > m) res = min (res, check());else {int ida[23];int i, j;for (i = 1; i <= m; i++) ida[i] = 23;for (i = 1; i <= m; i++)if (can (t, i))ida[i] = get_best (t, i);//neerly impossible bestvector<pair<int, int> >L;for (i = 1; i <= m; i++)if (ida[i] != 23) L.push_back (make_pair (ida[i], i));sort (L.begin(), L.end());for (i = 0; i < L.size(); i++)if (get_best (t, L[i].second) < res) {ch[t] = L[i].second;dfs (t + 1);}}}int main() {int i, j;while (cin >> m >> n) {for (i = 1; i <= n; i++) N[i].clear();for (j = 1; j <= m; j++) B[j].clear();for (j = 1; j <= m; j++) {for (i = 1; i <= n; i++) {int x;cin >> x;if (x) {B[j].push_back (i);N[i].push_back (j);}}}res = IDA (1, 1);dfs (0);cout << res - 1 << endl;}return 0;}