CF498E Stairs and Line 题解

这篇博客介绍了CF498E Stairs and Lines问题的解决方案,重点在于动态规划的应用。作者指出问题可以通过状压解决,特别是关注轮廓线的状态。通过枚举轮廓线,可以将复杂度降低到O(n)。文章提到在状态转移过程中,横线仅影响当前位置,而竖线影响当前位置和后续位置,因此w1位置需要特殊处理,w0位置只有存在竖线的情况才是合法的。

CF498E Stairs and Lines

CF498E Stairs and Lines

肯定是状压,而且状压的就是轮廓线,我们考虑同时状压横着和竖着的情况。然后肯定需要进行矩阵快速幂复杂度还是很高的。

但是我们考虑我们当前位置和之前位置进行转移的时候使用的是竖着的线,而且横着的线仅仅在当前转移出现了,意味着肯定不会影响后面的计算。那么我们不妨枚举轮廓线,这样复杂度就是直接少了 2 7 3 2^{7^3} 273

然后说几个细节,具体状态转移就自己推吧。我的写法是考虑当前位置和后面位置的衔接,对于也就是 w 1 w_1 w1 我们特殊处理一下 w 0 w_0 w0 也就是只有一个位置(存在竖线)是合法的。不然的话因为没有点所以只能是 0 0 0

#include <bits/stdc++.h>
using namespace std;

//#define Fread
//#define Getmod

#ifdef Fread
char buf[1 << 21], *iS, *iT;
#define gc() (iS == iT ? (iT = (iS = buf) + fread (buf, 1, 1 << 21, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
#define getchar gc
#endif // Fread

template <typename T>
void r1(T &x) {
	x = 0;
	char c(getchar());
	int f(1);
	for(; c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
	for(; '0' <= c && c <= '9';c = getchar()) x = (x * 10) + (c ^ 48);
	x *= f;
}

template <typename T,typename... Args> inline void r1(T& t, Args&... args) {
    r1(t);  r1(args...);
}

#ifdef Getmod
const int mod  = 1e9 + 7;// orz
template <int mod>
struct typemod {
    int z;
    typemod(int a = 0) : z(a) {}
    inline int inc(int a,int b) const {return a += b - mod, a + ((a >> 31) & mod);}
    inline int dec(int a,int b) const {return a -= b, a + ((a >> 31) & mod);}
    inline int mul(int a,int b) const {return 1ll * a * b % mod;}
    typemod<mod> operator + (const typemod<mod> &x) const {return typemod(inc(z, x.z));}
    typemod<mod> operator - (const typemod<mod> &x) const {return typemod(dec(z, x.z));}
    typemod<mod> operator * (const typemod<mod> &x) const {return typemod(mul(z, x.z));}
    typemod<mod>& operator += (const typemod<mod> &x) {*this = *this + x; return *this;}
    typemod<mod>& operator -= (const typemod<mod> &x) {*this = *this - x; return *this;}
    typemod<mod>& operator *= (const typemod<mod> &x) {*this = *this * x; return *this;}
    int operator == (const typemod<mod> &x) const {return x.z == z;}
    int operator != (const typemod<mod> &x) const {return x.z != z;}
};
typedef typemod<mod> Tm;
#endif

#define int long long
const int maxn = 7e3 + 5;
const int maxm = maxn << 1;
const int mod = 1e9 + 7;
struct Matrix {
    int n, m, a[128][128];
    Matrix(void) { memset(a, 0, sizeof(a)); }
//    Matrix operator * (const Matrix &z) const {
//        Matrix res; res.n = z.n, res.m = m;
//        for(int i = 0; i <= res.n; ++ i) {
//            for(int j = 0; j <= res.m; ++ j) {
//                for(int k = 0; k <= n; ++ k)
//                    res.a[i][j] = (res.a[i][j] + 1ll * a[k][j] * z.a[i][k] % mod) % mod;
//            }
//        }
//        return res;
//    }
    friend Matrix operator * (const Matrix &a, const Matrix &b) {
        Matrix res; res.n = b.n, res.m = a.m;
        for(int i = 0; i <= res.n; ++ i) {
            for(int j = 0; j <= res.m; ++ j) {
                res.a[i][j] = 0;
                for(int k = 0; k <= a.n; ++ k)
                    res.a[i][j] = (res.a[i][j] + 1ll * a.a[k][j] * b.a[i][k] % mod) % mod;
            }
        }
        return res;
    }
}Ans, S;

void ksm(Matrix &res, Matrix tmp,int mi) {
    while(mi) {
        if(mi & 1) res = res * tmp;
        mi >>= 1;
        tmp = tmp * tmp;
    }
}

int dp[maxn][128], c[128][128], w[10];

signed main() {
//    freopen("S.in", "r", stdin);
//    freopen("S.out", "w", stdout);
    int i, j;
    Ans.n = 127;
    int mx(0);
    for(i = 1; i <= 7; ++ i) {
        r1(w[i]);
        if(w[i]) mx = i;
    }
    int now(0), tmp(0);
    if(w[1] == 0) dp[now][1] = 1;
    else dp[now][0] = 1;
    c[0][0] = c[1][0] = c[0][1] = 1;
    for(i = 1; i <= mx; ++ i) {
        tmp |= (1 << i);
        if(w[i]) {
            Ans.n = S.n = S.m = (1 << i) - 1;
            for(j = 0; j < (1 << i); ++ j)
                Ans.a[j][0] = dp[now][j];
            for(j = 0; j < (1 << i); ++ j) {
                for(int k = 0; k < (1 << i); ++ k) {
                    S.a[j][k] = c[j][k];
                }
            }
            ksm(Ans, S, w[i] - 1);
            for(j = 0; j < (1 << i); ++ j)
                dp[now][j] = Ans.a[j][0];
        }
        memset(c, 0, sizeof(c));
        if(w[i + 1]) {
            ++ now;
            for(int k = 0; k < (1 << (i + 1)); ++ k)
            for(int s = 0; s < (1 << i); ++ s)
            for(j = 0; j < (1 << (i + 1)); ++ j) {
                if(!(j & k & (s | (1 << i)) & ((s << 1) | 1)))
                    c[j][k] ++;
                if(!((j | tmp) & k & (s | (1 << i)) & ((s << 1) | 1)))
                    dp[now][k] = (dp[now][k] + dp[now - 1][j]) % mod;
            }
            tmp = (1 << (i + 1));
        }
    }
    printf("%lld\n", dp[now][(1 << mx) - 1]);
	return 0;
}
步态相位检测是通过机器学习技术进行步行和上下楼梯的监测和识别。 步态相位是指一个完整步行周期中的不同阶段,包括踏步阶段和摆动阶段。通过准确识别步态相位,我们可以更好地了解个体的步行和运动模式。 使用机器学习方法来进行步态相位检测具有很大的优势。我们可以收集大量的步行和上下楼梯的数据作为训练集,并提取大量的特征,例如步伐周期、步幅、加速度等等。然后,我们可以使用这些特征来训练一个机器学习模型,例如支持向量机、决策树或神经网络模型。 训练完成后,我们可以将模型应用到实际的步行和上下楼梯的数据中,用于步态相位的检测。模型可以通过分析实时传感器数据,例如加速度计和陀螺仪数据,来判断当前的步行阶段。根据模型的输出,我们可以准确地确定个体当前所处的步态相位,从而监测其步行或运动状态。 步态相位检测在临床医学、康复训练和运动健康领域具有广泛的应用。通过检测个体的步态相位,我们可以评估其步行能力、平衡性和运动控制水平。对于康复训练,可以帮助康复师确定个体的康复进展和制定更加个性化的康复方案。同时,还可以用于监测运动员的训练状态和预防运动损伤。 总之,利用机器学习技术进行步态相位检测,可以提供准确和实时的步行和上下楼梯监测。这项技术在不同领域具有广泛的应用前景,并有助于改善个体的健康和运动表现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值