题意:
 |
i (tester) |
j (testee)/td> |
test outcome ai,j |
truth-teller |
truth-teller |
0 |
truth-teller |
liar |
1 |
liar |
truth-teller |
0 or 1 |
liar |
liar |
0 or 1 |
|
不用说了吧
解法:
这题我开始往2-sat的方向去想,搞死了搞不出来,今天洗澡的时候忽然发现。。这题原来是一个水了不能再水的DP
首先,设置DP状态(pos,left,jud),即决策到第pos个人时还允许有left个人是骗子,并且第pos个人是诚实的/骗子时的状态。
状态是一个集合,我用的bitset。
关于状态转移就很简单了
分2种情况:
1、第pos个人是骗子,那么第pos+1个人是诚实的或者骗子都可以
2、第pos个人是诚实的,那么第pos+1个人只能根据第pos个人说的话来决定
第一个人的情况要枚举,并且最后特别判断下
还有就是,集合初始化为全1,然后状态的运算是与运算。注意滚动数组,不然MLE到你哭~
代码:
1
# include <cstdio>
2
# include <cstring>
3
# include <bitset>
4
using namespace std;
5
# define N 1005
6
bitset<N> dp[2][N][2],one,zero;
7
int data[N],n,maxnum;
8
int main()
9

{
10
int test;
11
scanf("%d",&test);
12
one.set();
13
zero.reset();
14
while(test--)
15
{
16
one.set();
17
zero.reset();
18
scanf("%d%d",&n,&maxnum);
19
for(int i=0;i<n;i++)
20
scanf("%d",data+i);
21
bitset<N> res=one;
22
for(int i=0;i<=maxnum;i++)
23
dp[0][i][0]=zero,dp[0][i][1]=one;
24
for(int i=1;i<=n;i++)
25
{
26
for(int j=0;j<=maxnum;j++)
27
dp[i%2][j][0]=dp[i%2][j][1]=one;
28
for(int j=0;j<=maxnum;j++)
29
dp[i%2][j][0]&=dp[(i-1)%2][j][1];
30
for(int j=0;j<maxnum;j++)
31
dp[i%2][j][1]&=dp[(i-1)%2][j+1][1].set(i);
32
if(!data[i-1])
33
for(int j=0;j<=maxnum;j++)
34
dp[i%2][j][0]&=dp[(i-1)%2][j][0];
35
else
36
for(int j=0;j<maxnum;j++)
37
dp[i%2][j][1]&=dp[(i-1)%2][j+1][0].set(i);
38
}
39
for(int i=0;i<=maxnum;i++)
40
res&=dp[n%2][i][0];
41
42
for(int i=0;i<maxnum;i++)
43
dp[0][i][0]=one,dp[0][i][1]=zero.set(0);
44
dp[0][maxnum][0]=dp[0][maxnum][1]=one;
45
for(int i=1;i<=n;i++)
46
{
47
for(int j=0;j<=maxnum;j++)
48
dp[i%2][j][0]=dp[i%2][j][1]=one;
49
for(int j=0;j<=maxnum;j++)
50
dp[i%2][j][0]&=dp[(i-1)%2][j][1];
51
for(int j=0;j<maxnum;j++)
52
dp[i%2][j][1]&=dp[(i-1)%2][j+1][1].set(i);
53
if(!data[i-1])
54
for(int j=0;j<=maxnum;j++)
55
dp[i%2][j][0]&=dp[(i-1)%2][j][0];
56
else
57
for(int j=0;j<maxnum;j++)
58
dp[i%2][j][1]&=dp[(i-1)%2][j+1][0].set(i);
59
}
60
for(int i=0;i<maxnum;i++)
61
res&=dp[n%2][i][1];
62
63
64
if(res.count()==0) printf("0 0\n");
65
else
66
{
67
int pos=-1;
68
for(int i=0;i<n&&pos==-1;i++)
69
if(res[i])
70
pos=i;
71
printf("%d %d\n",res.count(),pos+1);
72
}
73
}
74
return 0;
75
}