CF1137 C. Museums Tour

CF1137 C. Museums Tour

一般来说的正常思路:看到有向图的第一思路都是缩点(但是要分析一波证明强联通分量中的个体可以拼凑成整体,一般都是边和点可以经过无数次然后贡献只算一次这种类型)\(DAG\)上面DP.

这道题第一眼看上去比较麻烦,因为这个时间限制比较恶心的样子.

我们考虑拆点,将一个点拆成\(d\)个,\((i,j)\)表示第\(i\)个点在第\(j\)天的联通情况

这样的话,我们在缩点的时候,就统计一下每一个强联通分量内有多少点在其对应的博物馆的开放时间内(注意去重)

这样的话,我们貌似就得到了每个强联通分量的点权

剩下的貌似就是一个\(DAG\)上的最长链问题了.

但是我们好像没有考虑一个点在两个或多个强联通分量都有贡献的情况

很幸运这是不需要考虑的.因为不可能出现上述情况

为什么?

我们说假设存在这样一次路径,满足\((i,x) ->(i,y)\)即从\(i\)点的第\(x\)天能够到达第\(i\)个点的第\(y\)天,我们设\(\Delta d = y - x\)(默认\(y\)大于\(x\))

那么一定存在\((i,0)->(i,d - 1)\)

以此类催,我们发现从\(y\)也可以到达\(x\),那么他们必在同一强联通分量内

然后就结束了

我栈用了存边数组的变量\(tot\)导致疯狂RE

#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
//const int N = 7;
const int mod = 1e9 + 7;
int a[9],b[9];
int dp[2][131][131];
int p[9];
int c[31][9];
int noip[9];
//0 =
//1:>
int n,m;
int now = 1;
inline void up(int &x,int y){
    x += y;
    if(x >= mod) x -= mod;
}
int main(){
    p[0] = 1;
    for(int i = 1;i <= n;++i) up(p[i],p[i - 1] << 1);
    scanf("%d%d",&n,&m);
    if(n == 1){printf("%d\n",p[m]);return 0;}
    for(int i = 1;i <= n;++i) scanf("%d",&b[i]);
    for(int i = 0;i < m;++i)
        for(int j = 0;j < n;++j)
            z[i][j] = (b[j] & (1 << i)) ? 1 : 0;
    
//  for(int i = m;i >= 0;--i){
//      for(int l = 0;l < (1 << (n - 1));++l){
//          for(int r = 0;r < (1 << (n - 1));++r){
//              for(int s = 0;s < (1 << n);++s){
//                  
//              }
//          }
//      }
//  }
//0 =
//1:>
    int size1 = 1 << (n - 1);
    int size2 = size1 << 1;
    dp[0][0][0] = 1;
    for(int i = m - 1;i >= 0;i--){
        for(int l = 0;l < size1;++l){
            for(int r = 0;r < size1;++r){
                if(dp[now ^ 1][l][r] == 0) continue;
                for(int s = 0;s < n;++s) if()
            }
        }   
    }
    return 0;   
}

猜你喜欢

转载自www.cnblogs.com/wyxdrqc/p/10966766.html