奶牛们喜欢在黑暗中睡觉。每天晚上,他们的牲口棚有L(3<=L<=50)盏灯,他们想让亮着的灯尽可能的少。他们知道按钮开关的位置,但喜闻乐见的是他们并没有手指。你得到了一个长度为T(1<=T<=7)的插槽用以帮助奶牛们改变灯的状态。
使用5次插槽
1111111111 初始状态
0010111111 对第一个位置使用插槽
0001101111 对第三个位置使用插槽
0000000111 对第四个位置使用插槽
0000011101 对第六个位置使用插槽
0000010000 对第七个位置使用插槽
可以证明这是满足字典序最小的最优解。
#include<cstdio> #include<iostream> using namespace std; int n,m; int f[51],t[51],i; char c[51]; int pos[51]; int ans[51],xp,o=50,sp=0; void u(){ if(sp>o) return; o=sp; for(i=1;i<=o;i++) ans[i]=pos[i]; } bool dfs(int yyt,int xx){ if (xx>xp) return 0; if (sp>o) return 0; if (yyt>n-m+1){ for (i=yyt;i<=n;i++) if (f[i]) xx++; if (xx>xp) return 0; u(); return 1; } for (i=1;i<=m;i++) f[yyt+i-1]^=t[i]; pos[++sp]=yyt; bool cmp=dfs(yyt+1,xx+f[yyt]); for (i=1;i<=m;i++) f[yyt+i-1]^=t[i]; sp--; cmp|=dfs(yyt+1,xx+f[yyt]); return cmp; } int main(){ scanf("%d%d",&n,&m); scanf("%s",c+1);for (i=1;i<=n;i++) f[i]=c[i]-48; scanf("%s",c+1);for (i=1;i<=m;i++) t[i]=c[i]-48; for (xp=0;xp<=n;xp++) if (dfs(1,0)) break; printf("%d\n",o); for (i=1;i<=o;i++) printf("%d\n",ans[i]); }
bzoj:1659: [Usaco2006 Mar]Lights Out 关灯
原文:http://www.cnblogs.com/Enceladus/p/5040110.html