Codeforeces #420 E. Okabe and El Psy Kongroo 递推加矩阵快速幂

比较好的一道题,首先是是递推,递推很容易想到,我们假设dp[i][j]表示走到i,j的方案数 那么其实就是求出每一段a[i]-b[i]的值 就可以得出来了

可以得到

dp[i][j+1] += dp[i-1][j]; j+1<=ci

dp[i][j-1] += dp[i-1][j];  j-1>=0

dp[i][j] += dp[i-1][j];

因为i的范围很大,看了解法后知道要用矩阵快速幂

我们构造一个16*16的矩阵 矩阵mat[i][j] 表示从y轴的i点走到y轴的j点的方案数,当长度为一的时候这个矩阵很好构造 那么长度为2的时候其实就是mat^2,那么直接快速幂求出长度为b[i]-a[i],然后每一段的方案知道后这个题就基本解决了 详细看代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cstring>

using namespace std;
#define LL long long
#define N 18
#define MOD 1000000007ll
struct Matrix{
    LL dat[N][N];
    int n;
    Matrix(){
        _init();
    }
    void _init(){
        memset(dat,0,sizeof(dat));
    }
    LL* const operator[](int i)
    {
		return dat[i];
    }
	const LL*  operator[](int i)const
	{
		return dat[i];
	}
    void operator%(LL mod)
    {
        for(int i = 0;i<n;i++)
        {
            for(int j = 0;j<n;j++)
            {
                dat[i][j]%=mod;
            }
        }
    }
    Matrix operator *(const Matrix& mat){
        Matrix temp;
        temp.n = mat.n;
        for(int i = 0;i<n;i++)
        {
            for(int j = 0;j<n;j++)
            {
                for(int k = 0;k<n;k++)
                {
                   temp[i][j] += dat[i][k]*mat[k][j];
                   temp[i][j]%=1000000007ll;
                }
            }
        }
        return temp;
    }
};
Matrix ans,sta;
void quickPow(LL len)
{
    while(len)
    {
        if(len&1)
        {
            ans = ans*sta;
            ans%MOD;
        }
        len >>= 1;
        sta = sta*sta;
        sta%MOD;
    }
}
int main()
{
    LL n,k;
    while(scanf("%lld%lld",&n,&k)!=EOF)
    {
        LL a[105],b[105],c[105];
        for(int i = 0;i<n;i++)
        {
            scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
        }
        ans._init();
        ans.n = 16;
        sta.n = 16;
        for(int i = 0;i<=ans.n;i++)
        {
            ans[i][i] = 1;
        }
        sta._init();

        for(int i = 0;i<n;i++)
        {
            sta._init();
            for(int j = 0;j<=c[i];j++)
            {
                if(j+1<=c[i])
                    sta[j][j+1]++;
                if(j-1>=0)
                    sta[j][j-1]++;
                sta[j][j]++;
            }
            if(b[i]>k)
            {
                quickPow(k-a[i]);
            }
            else quickPow(b[i]-a[i]);
        }

        printf("%lld\n",ans[0][0]);
    }
	return 0;
}


由于时空Kriging是一个理论与实践相结合的过程,直接提供完整的Python代码片段比较困难,因为这通常涉及特定的数据结构、库(如Geostatistics库如PyKrige或R语言中的gstat)以及详细的设置。但是,我可以给出一个大致的概念框架: ```python # 假设你已经安装了geopandas, numpy, pykrige等库 import geopandas as gpd from pykrige.ok import OK import numpy as np # 假设df是你的数据框,包含了位置(x),时间(y),及对应f值 df = pd.DataFrame({ &#39;x&#39;: [1, 2, 3, 4], # 空间位置 &#39;y&#39;: [&#39;y1&#39;, &#39;y2&#39;, &#39;y3&#39;, &#39;y4&#39;], # 时间 &#39;f_value&#39;: [your_values] # 对应的f值 }) # 将x和y转换为适合作为空间和时间坐标的数据结构 coordinates = [(x, y) for x, y in zip(df[&#39;x&#39;].values, df[&#39;y&#39;])] # 创建OK实例(Okabe-Envelope Kriging) kriging_model = OK() # 训练模型,这里假设kriging_model.fit()需要输入DataFrame的坐标和f_value列 kriging_model.fit(coordinates, df[&#39;f_value&#39;]) # 设定未来预测的位置 (future_x, future_y) future_coordinates = [(future_x, future_time) for future_x in {future_x1, future_x2, ...} for future_time in {&#39;future_y1&#39;, &#39;future_y2&#39;, ...}] # 预测未来的f值 predicted_f_values = kriging_model.predict(future_coordinates) print(predicted_f_values) ``` 请注意,上述代码仅为示例,实际操作中可能需要调整参数、异常处理和更详细的数据预处理步骤。具体的实现细节取决于你的数据和使用的库版本。如果你需要详细了解如何使用某个特定库,建议查阅官方文档或在线教程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值