zoukankan      html  css  js  c++  java
  • POJ

    POJ - 3254

    中文题。。

    思路:这题可把我恶心坏了,我刚开始的思路其实是正确的。。。 

    首先我想开个dp[i][s1][s2]保存到 i行 为止当前行状态为s1,上一行状态为s2 的最大个数,然后我先把满足行内条件的

    状态存起来,空间用滚动数组优化,但是我在写转移方程的时候发现复杂度太大。。。。 其实复杂度是够的,因为一行里面

    满足行内条件的最多有60个合法状态,哈希一下就好啦,都不用滚动数组。。。 

    然后我又开脑洞去搞三进制的状态压缩,写到最后发现复杂度又不对,才发现原来的方法是正确的。。。。

      1 #include<cstdio>
      2 #include<vector>
      3 #define fi first
      4 #define se second
      5 #define mk make_pair
      6 #define pii pair<int,int>
      7 #define read(x) scanf("%d",&x)
      8 #define sread(x) scanf("%s",x)
      9 #define dread(x) scanf("%lf",&x)
     10 #define lread(x) scanf("%lld",&x)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int inf=0x3f3f3f3f;
     15 const int INF=0x3f3f3f3f3f3f3f3f;
     16 const int N=107;
     17 const int M=10;
     18 const int mod=1e8;
     19 
     20 int n,m,dp[101][70][70],f[N];
     21 char s[20];
     22 vector<int> v,num;
     23 bool check(int x)
     24 {
     25     int cnt=2,cur=x;
     26     while(x)
     27     {
     28         int now=x%2;
     29         if(cnt<2 && now)
     30             return false;
     31         if(now) cnt=0;
     32         else cnt++;
     33         x/=2;
     34     }
     35     return true;
     36 }
     37 int cal(int x)
     38 {
     39     int ans=0;
     40     while(x)
     41         x-=x&-x,ans++;
     42     return ans;
     43 }
     44 int main()
     45 {
     46     read(n); read(m);
     47     for(int i=0;i<n;i++)
     48     {
     49         scanf("%s",s);
     50         for(int j=0;j<m;j++)
     51             f[i]*=2,f[i]+=s[j]=='P'? 1:0;
     52     }
     53     int up=1<<m;
     54     for(int i=0;i<up;i++)
     55     {
     56         if(check(i))
     57         {
     58             v.push_back(i);
     59             num.push_back(cal(i));
     60         }
     61     }
     62     int sz=v.size();
     63     for(int i=0;i<sz;i++)
     64     {
     65         int s1=v[i];
     66         if((s1|f[0])!=f[0])
     67             continue;
     68         for(int j=0;j<sz;j++)
     69         {
     70             int s2=v[j];
     71             if((s2|f[1])!=f[1] || (s1&s2))
     72                 continue;
     73             dp[1][i][j]=num[i]+num[j];
     74         }
     75     }
     76     for(int i=2;i<n;i++)
     77     {
     78         for(int j=0;j<sz;j++)
     79         {
     80             for(int k=0;k<sz;k++)
     81             {
     82                 for(int u=0;u<sz;u++)
     83                 {
     84                     int s1=v[j],s2=v[k],s3=v[u];
     85                     if((s1&s2) || (s1&s3) || (s1|f[i])!=f[i])
     86                         continue;
     87                     dp[i][k][j]=max(dp[i][k][j],dp[i-1][u][k]+num[j]);
     88                 }
     89             }
     90         }
     91     }
     92     int ans=0;
     93     if(n!=1)
     94     {
     95         for(int i=0;i<sz;i++)
     96             for(int j=0;j<sz;j++)
     97                 ans=max(ans,dp[n-1][i][j]);
     98     }
     99     else
    100     {
    101         for(int i=0;i<sz;i++)
    102             if((v[i]|f[0])==f[0])
    103                 ans=max(ans,num[i]);
    104     }
    105     printf("%d
    ",ans);
    106 }
    107 /*
    108 */
  • 相关阅读:
    作业: 小型购物系统1---按顺序编写
    字典操作学习小结
    字符操作学习笔记小结
    列表,元组等学习笔记小结
    模块及其数据类型小结
    python3学习笔记----基础知识1
    压力山大
    下周一开始上班啦!
    凌晨12点,沉迷学习,无法自拔...
    web前端开发2018年12月找工作总结
  • 原文地址:https://www.cnblogs.com/CJLHY/p/8520140.html
Copyright © 2011-2022 走看看