日常补

本文探讨了在D维空间中访问所有点的最少旅行次数问题及骨牌倒下的期望触碰次数。通过动态规划算法解决空间旅行问题,并利用概率论解决骨牌问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D 维空间里有一个关于点的集合 S,集合中的点的第 i 维坐标 ai 满足 1≤ai≤di ,其中 di 是给定的正整数 ,所以 S 中总共有 ∏di 个点。

定义一次空间旅行是指,从 (1,1,⋯,1) 开始进行移动,每次移动只能将某一维坐标加 1 、其他维坐标不变,从而走到下一个点,然后继续进行移动,每次移动前也可以选择结束此次旅行。

问至少进行多少次空间旅行,才能将 S 中所有的点都访问至少一次。

/*https://biancheng.love/contest-ng/index.html#/123*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL INF = (1uLL << 63) - 1;
const LL mod = 1000000007;
const int N = 1e5 + 5;
const double Pi = acos(-1.0);
const int maxn = 2e6 + 5;
int dp[25][maxn];
int sum[25][maxn];
int d[25];
int n , m;
int gao() {
    dp[0][0] = 1;
    /**
        dp[i][j]表示在前i维内添加j所具有的状态数
        dp[i][j] = sum(dp[i-1][k]) --------- 0 <= k <= j && j - k < di,di表示第i维的大小
        dp[i-1][j]表示给第i维加上0,dp[i-1][j-1]表示给第i维加上1~~~~类推得dp[i-1][0]是给第i维的数字加上k
        但是复杂度过高,用sum处理前缀和优化复杂度
        所以
        sum[i][j] = sum[i][j-1]+dp[i][j];
        dp[i][j] = dp[i-1][j]+dp[i-1][j-1]+...+dp[i-1][j - di + 1] = sum[i-1][j] - sum[i-1][j - di];

    **/
    for(int i = 0; i <= m; i++)sum[0][i] = 1;
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j <= m; j++) {
            if(j < d[i]) {
                dp[i][j] = sum[i - 1][j];
            }
            else dp[i][j] = sum[i - 1][j] - sum[i - 1][j - d[i]];
            sum[i][j] = (j ? sum[i][j - 1] : 0) + dp[i][j];
        }
    }

    int res = 0;
    for(int i = 0; i <= m; i++) {
        res = max(dp[n][i], res);
    }
    return res;
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif
    int cas;
    cin >> cas;
    while(cas--) {
        /**
            画一下从(1,1,1)作为根往下拓展的图可知
            (d1,d2,...dn)的答案应该是这个图中某一层的结点个数最多的个数

            !!! 可以把这个问题转化成
            (1,1,1,1....),分配x个1到这上面,具有的状态最多

            然后就是dp了。。
              ---------thx zk && from zk
        **/
        cin >> n;
        m = - n;
        for(int i = 1 ; i <= n ; i++) {
            scanf("%d", &d[i]);
            m += d[i];
        }
        cout << gao() << endl;
    }
}

constroy 喜欢玩多米诺骨牌,他把若干块骨牌排列成一个 n 行 m 列的矩阵准备进行游戏。

但是 constroy 太笨了,他无法用一次触碰使所有的骨牌全部倒下。于是,他从第一行第一列的骨牌开始检查,依次检查第一行第二列,第一行第三列,……,第二行第一列,第二行第二列,……,第 n 行第 m 列的骨牌。如果他检查到一块骨牌没有倒下,那么他就会触碰它。而第 i 行第 j 列立着的骨牌被触碰时,有 pi,j 的概率向下一行倒,有 qi,j 的概率向下一列倒,并触碰该方向上与其相邻的骨牌(如果存在)。

请你估计一下笨拙的 constroy 总共触碰骨牌次数的期望值是多少吧。

提示:期望值是试验中每次可能结果的概率乘以其结果的总和。

这题。。。
注意是从左到右触碰骨牌还有骨牌只往下和往右倒。。。没注意这个样例都不会推。。。

本想求出触碰次数的概率。。然后再求期望。。但是这样太难。。
然后被教了一发,先考虑
每个骨牌要被触碰的概率,因为每个骨牌最多被触碰一次,所以他们的和也就是答案要求的期望

就是从整体拆成了每个点的样子=_=不知道怎么表述
但是好像博客里的邮票那题也是这样做的。。。我还是忘了啊啊啊

然后考虑每个点如果会被触碰,那么就是上方的点不往下倒&&左边的点也不往右倒,所以p = 1 - (pa + pb - pa*pb);
这是个概率公式= =实在不行画个两个相交的圆求(1 - 并集)也可以理解= =

/*https://biancheng.love/contest-ng/index.html#/123*/
#include <set>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>

#define  mp make_pair
#define pb push_back
#define  X first
#define  Y second

using namespace std;
typedef long long LL;
const int maxn = 505;
int n, m;
double righ[maxn][maxn],down[maxn][maxn];
void init() {

    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n,&m);
        double ans = 0;

        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lf",&down[i][j]);

        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lf",&righ[i][j]);

        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            double t =1 - (down[i-1][j] + righ[i][j-1] - down[i-1][j]*righ[i][j-1]);
            ans+=t;

        }
        printf("%.4lf\n",ans);
    }
}
int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    init();

    return 0;
}

Tangjz 在二维平面上发现了 n 个互异的整点。

他很好奇,能否从中选出 m 个点恰好构成正多边形 (m≥3)(m≥3) 呢?

如果可以,请输出最大的 m ;如果不可以,请输出 -1 。

这题。。。因为点都是整点所以一定是正方形。。。想不到啊啊啊啊
所以就是判断m个点是否有正方形存在,剩下的就是枚举两点,再二分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值