openJudge C17K:Lying Island

地址:http://poj.openjudge.cn/practice/C17K/

题目:

C17K:Lying Island

总时间限制: 
2000ms

内存限制: 
262144kB
描述

There are N people living on Lying Island. Some of them are good guys, while others are bad.

It is known that good guys are always telling truths, while bad guys may be telling either truths or lies.

One day, an investigator came to Lying Island. He wondered how many good guys are there on the island. So he conducted an investigation.

People on the island are numbered from 1 to N. When the investigator was interviewing person i, he showed the islander the information about at most K people numbered from max{i-K,1} to (i-1).

Sometimes, the i-th islander would say, "Oh, person x is a good(bad) guy."

But sometimes, the i-th islander would mince his words, "Eh, if person x is a good(bad) guy, person y is a good(bad) guy."

Of course, x and y is less than i but no less than (i-K), because person i only saw the information of that at most K islanders.

The investigator does not think he can infer exactly how many good guys on the island from these words, but he feels that he can figure out how many good guys at most on the island. Can you help him?

输入
The first line contains an integer T (1 <= T <= 50), indicating the number of test cases.

For each test case:

The first line contains two integers N and K (0 <= N <= 5000,1 <= K <= 10).

Then (N-1) lines follow, each line contains a string, indicating the sentences said by person 2 to person N. Each sentence is in one of the following formats:
1. Person i: Person x is a good guy.
2. Person i: Person x is a bad guy.
3. Person i: If person x is a good guy, person y is a good guy.
4. Person i: If person x is a bad guy, person y is a bad guy.
It is guaranteed that in each sentence, max{1,i-K} <= x,y < i and x ≠ y.

输出
For each test case, output one integer on a single line, indicating the number of good guys at most on the island.
样例输入
2
7 2
Person 2: Person 1 is a good guy.
Person 3: Person 2 is a bad guy.
Person 4: If person 3 is a good guy, person 2 is a good guy.
Person 5: If person 4 is a good guy, person 3 is a bad guy.
Person 6: If person 5 is a bad guy, person 4 is a good guy.
Person 7: If person 6 is a bad guy, person 5 is a bad guy.
7 4
Person 2: Person 1 is a bad guy.
Person 3: Person 2 is a bad guy.
Person 4: If person 3 is a good guy, person 1 is a bad guy.
Person 5: Person 2 is a bad guy.
Person 6: If person 4 is a good guy, person 2 is a bad guy.
Person 7: Person 6 is a bad guy.
样例输出
6
4
提示
For the first test case, person 3 is a bad guy, and others are good.
Person 1: Person 1 said nothing, he is a good guy.
Person 2: Person 1 is indeed a good guy, and person 2 is saying the truth.
Person 3: Person 2 is not a bad guy, and person 3 is lying.
Person 4: Person 3 is not a good guy, so the prerequisite does not met. Person 4 is saying the truth.
Person 5: Person 4 is indeed a good guy and person 3 is indeed a bad guy. Person 5 is saying the truth.
Person 6: Person 5 is a good guy. Person 6 is saying the truth.
Person 7: Person 6 is a good guy. Person 7 is saying the truth.
思路:状压DP,把包括当前位的前十位状压进去就好了,然后转移。

#include <bits/stdc++.h>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int,int> PII;
const double eps=1e-8;
const double pi=acos(-1.0);
const int K=5e3+7;
const int mod=1e9+7;

int n,ans,k,dp[K][1<<10];
char sa[200];

int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        memset(dp,-1,sizeof dp);
        for(int i=0,mx=(1<<9);i<mx;i++)
            dp[1][i]=0;
        for(int i=(1<<9),mx=(1<<10);i<mx;i++)
            dp[1][i]=1;
        for(int i=2,x,y,dx,dy;i<=n;i++)
        {
            scanf("%s%d%s%s",sa,&x,sa,sa);
            if(sa[0]==‘P‘)
            {
                scanf("%d%s%s%s",&x,sa,sa,sa);
                if(sa[0]==‘b‘)  dx=0;
                else    dx=1;
                gets(sa);
                for(int j=0,mx=1<<10;j<mx;j++)
                if(((j>>(x-i+10))&1)==dx&&~dp[i-1][j])
                    dp[i][(j+mx)>>1]=max(dp[i-1][j]+1,dp[i][(j+mx)>>1]);
                for(int j=0,mx=(1<<10);j<mx;j++)
                    dp[i][j>>1]=max(dp[i][j>>1],dp[i-1][j]);
            }
            else
            {
                scanf("%s%d%s%s%s",sa,&x,sa,sa,sa);
                if(sa[0]==‘b‘)   dx=0;
                else    dx=1;
                scanf("%s%s%d%s%s%s",sa,sa,&y,sa,sa,sa);
                if(sa[0]==‘b‘)   dy=0;
                else    dy=1;
                gets(sa);
                for(int j=0,mx=1<<10;j<mx;j++)
                if(~dp[i-1][j] && !(((j>>(x-i+10))&1)==dx&&((j>>(y-i+10))&1)!=dy))
                    dp[i][(j+mx)>>1]=max(dp[i-1][j]+1,dp[i][(j+mx)>>1]);
                for(int j=0,mx=(1<<10);j<mx;j++)
                    dp[i][j>>1]=max(dp[i-1][j],dp[i][j>>1]);
            }
        }
        ans=0;
        for(int i=0,mx=(1<<10);i<mx;i++)
            ans=max(ans,dp[n][i]);
        printf("%d\n",ans);
    }
    return 0;
}

/*
Person 2: Person 1 is a bad guy.
Person 3: Person 2 is a bad guy.
Person 4: Person 3 is a bad guy.
Person 5: Person 4 is a bad guy.

Person 2: Person 1 is a good guy.
Person 3: Person 2 is a good guy.
Person 4: Person 3 is a bad guy.
Person 5: Person 4 is a good guy.
*/

时间: 2024-08-08 13:56:07

openJudge C17K:Lying Island的相关文章

PKU_campus_2017_K Lying Island

思路: 题目链接http://poj.openjudge.cn/practice/C17K/ 状压dp.dp[i][j]表示第i - k人到第i人的状态为j的情况下前i人中最多有多少好人. 实现: 1 #include <bits/stdc++.h> 2 using namespace std; 3 int dp[2][2049]; 4 struct node 5 { 6 int type, id1, id2; 7 bool f1, f2; 8 }; 9 node a[5001]; 10 bo

Poj 1328 / OpenJudge 1328 Radar Installation

1.Link: http://poj.org/problem?id=1328 http://bailian.openjudge.cn/practice/1328/ 2.Content: Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 52833   Accepted: 11891 Description Assume the coasting is an infinite straig

LightOJ 1418 Trees on My Island (Pick定理)

题目链接:LightOJ 1418 Problem Description I have bought an island where I want to plant trees in rows and columns. So, the trees will form a rectangular grid and each of them can be thought of having integer coordinates by taking a suitable grid point as

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

463 Island Perimeter

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one isla

Leetcode-463 Island Perimeter

#463. Island Perimeter You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and th

Gym 100971A Treasure Island BFS 思维题

A - Treasure Island Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description standard input/output Announcement Statements Pirate John Silver has found a map depicting exactly one island in a sea. The ma

Poj OpenJudge 1068 Parencodings

1.Link: http://poj.org/problem?id=1068 http://bailian.openjudge.cn/practice/1068 2.Content: Parencodings Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20077   Accepted: 12122 Description Let S = s1 s2...s2n be a well-formed string of p

OpenJudge 2721 忽略大小写比较字符串大小

1.Link: http://bailian.openjudge.cn/practice/2721/ 2.Content: 总时间限制: 1000ms 内存限制: 65536kB 描述 一般我们用strcmp可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同 的字符或遇到'\0'为止.如果全部字符都相同,则认为相同:如果出现不相同的字符,则以第一个不相同的字符的比较结果为准.但在有些时候,我们比较字符 串的大小时,希望忽略字母的大小,例