您的位置:首页 > 其它

1659: [Usaco2006 Mar]Lights Out 关灯

2015-09-23 17:12 295 查看

1659: [Usaco2006 Mar]Lights Out 关灯

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 207  Solved: 30

[Submit][Status][Discuss]

Description

奶牛们喜欢在黑暗中睡觉。每天晚上,他们的牲口棚有L(3<=L<=50)盏灯,他们想让亮着的灯尽可能的少。他们知道按钮开关的位置,但喜闻乐见的是他们并没有手指。你得到了一个长度为T(1<=T<=7)的插槽用以帮助奶牛们改变灯的状态。

Input

第一行,两个整数L和T。第二行给出一个长度为L的01串表示初始灯的状态,0表示灯是灭的,1表示灯是亮的。第三行给出一个长度为T的01串,表示你获得的插槽。

Output

第一行输出一个整数K,表示在满足亮着的灯最少的情况下,你要用插槽操作的次数。第二行到第K+1行,每行一个整数表示你的插槽使用的位置。
"K最小的解,并且满足解的字典序最大(即按钮开关的位置尽可能靠后)"

Sample Input

10 4

1111111111

1101

Sample Output

5

1

3

4

6

7

HINT

使用5次插槽

1111111111  初始状态

0010111111  对第一个位置使用插槽

0001101111  对第三个位置使用插槽

0000000111  对第四个位置使用插槽

0000011101  对第六个位置使用插槽

0000010000  对第七个位置使用插槽

可以证明这是满足字典序最小的最优解。


在BZOJ上很开心地做到一道学长翻译,学长改数据,学长写题解的题。。。




先上一发图,嗯。。。大神思路先膜拜几分钟
然后是弱弱弱在此思路上自己打的代码。。

#include<cstdio>

#include<iostream>

#include<cmath>

using namespace std;

const int maxn = 60;

int n,m,i,L,s[maxn],t[maxn],ans[maxn],Try[maxn],num = 1E9;

char S[maxn],T[maxn];

bool dfs(int k,int now,int l)

{
bool tmp = false;
if (now > num) return false;
if (l > L) return false;
if (k > n - m + 1)
{
int tot = l;
for (int j = k; j <= n; j++) tot += s[j];
if (tot > L) return false;
for (int j = 1; j <= now; j++) ans[j] = Try[j];
num = now;
return true;
}
for (int j = k; j <= k + m - 1; j++) s[j] ^= t[j-k+1];
Try[now + 1] = k;
tmp = dfs(k+1,now+1,l+s[k]);
for (int j = k; j <= k + m - 1; j++) s[j] ^= t[j-k+1];
tmp = dfs(k+1,now,l+s[k]) || tmp;
return tmp;

}

int main()

{
//freopen("yzy.txt","r",stdin);
cin >> n >> m;
cin >> 1+S;
cin >> 1+T;
for (i = 1; i <= n; i++) s[i] = S[i] - '0';
for (i = 1; i <= m; i++) t[i] = T[i] - '0';
for (L = 0; L <= n; L++)
 if (dfs(1,0,0)) break;
printf("%d\n",num);
for (i = 1; i <= num; i++) printf("%d\n",ans[i]);
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: