zoukankan      html  css  js  c++  java
  • C17K:Lying Island

    链接

    题意:

      有n个人,每个人可能会说:

    • 第x个人是好人/坏人
    • 如果第x个人是好人/坏人,则第y个人是好人/坏人

    思路:

      状压dp,首先每个人所说的人只能是他前面10个人,所以对于第i个人记录下,他前面十个人的情况。

      对于第i个人,如果他说的话一个状态不冲突,那么i可以由这个状态转移。

      注意:对于“如果第x个人是好人,那么第y个人是坏人 “,那么x是好人,y是好人是不满足的。但是除了x是好人y是坏人这种情况满足,x是坏人,也是满足的。(一定要学好语文!)

    代码

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 
     7 using namespace std;
     8 
     9 int dp[5010][1050];
    10 char str[50];
    11 int k;
    12 
    13 void work1(int i,int x,int z) {
    14     int t = (1 << k);
    15     for (int j=0; j<t; ++j) {
    16         if (((j>>(x-i+k))&1)==z) dp[i][(j+t)>>1] = max(dp[i][(j+t)>>1],dp[i-1][j]+1);
    17         dp[i][j>>1] = max(dp[i][j>>1],dp[i-1][j]); 
    18     }
    19 }
    20 void work2(int i,int x,int y,int z1,int z2) {
    21     int t = (1 << k);
    22     for (int j=0; j<t; ++j) {
    23         int t1 = ((j>>(x-i+k))&1) == z1,t2 = ((j>>(y-i+k))&1) != z2;
    24         if (!(t1&&t2)) dp[i][(j+t)>>1] = max(dp[i][(j+t)>>1],dp[i-1][j]+1);
    25         dp[i][j>>1] = max(dp[i][j>>1],dp[i-1][j]);
    26     }
    27 }
    28 int main() {
    29     int T,n,x,y,z; 
    30     scanf("%d",&T);
    31     while (T--) {
    32         scanf("%d%d",&n,&k);
    33         memset(dp,-1,sizeof(dp));
    34         for (int j=0,t=(1<<(k-1)); j<t; ++j) dp[1][j] = 0;
    35         for (int j=(1<<(k-1)),t=(1<<k); j<t; ++j) dp[1][j] = 1;
    36         
    37         for (int i=2; i<=n; ++i) {
    38             scanf("%s%s%s%d",str,str,str,&x);
    39             if (str[0]=='P') {
    40                 scanf("%s%s%s",str,str,str);
    41                 if (str[0]=='g') z = 1;
    42                 else z = 0;
    43                 scanf("%s",str);
    44                 work1(i,x,z);
    45             }
    46             else {
    47                 scanf("%s%d%s%s%s",str,&x,str,str,str);
    48                 if (str[0]=='g') z = 1;
    49                 else z = 0;
    50                 scanf("%s%s%d%s%s%s",str,str,&y,str,str,str);
    51                 work2(i,x,y,z,str[0]=='g');
    52                 scanf("%s",str);
    53             }
    54         }
    55         int ans = 0;
    56         for (int i=0,t=(1<<k); i<t; ++i) ans = max(ans,dp[n][i]);
    57         printf("%d
    ",ans); 
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    54. 八皇后问题[eight queens puzzle]
    53. 特殊的O(n)时间排序[sort ages with hashtable]
    52. 不用+、-、×、÷做加法[add two numbers without arithmetic]
    C++基础知识面试精选100题系列(11-20题)[C++ basics]
    C++基础知识面试精选100题系列(1-10题)[C++ basics]
    洛谷 P1479 宿舍里的故事之五子棋
    洛谷 P2084 进制转换
    codevs 1700 施工方案第二季
    POJ 3278 Catch That Cow(求助大佬)
    POJ 2251 Dungeon Master
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8969117.html
Copyright © 2011-2022 走看看