搞个大矩阵(动态规划+bitset加速+滚动数组)(北理16校赛)

hybest在被诅咒的矩阵中寻找最快路线,吸收最多查克拉之果。每个位置的果数等于到该位置的最短路径数乘以y。使用动态规划结合bitset优化,解决步数限制和取模运算问题。给定矩阵大小、出口位置、模数k和y,求解最大果数。

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

时间限制1秒 内存限制153600KB

题目描述:

        hybest担任着拯救文太的任务。
        有一天在施展膜法的时候,不小心转移到一个被施下诅咒的矩阵之中。他在矩阵中可以向着相邻的格子移动(斜向的移动是不允许的)。
        矩阵每个位置都有很多可以采摘的查克拉之果,hybest要走出这个矩阵,他每经过一个位置,这个位置的查克拉之果都会被他吸收。
        但是由于矩阵里存在强大的诅咒,hybest在走出矩阵时,获得的查克拉之果数量会被做一个取模运算,模 k 。

        hybest想通过膜法探知这个矩阵的真相,于是他在法阵之中召唤出了上古神谕,神谕上写道:
        矩阵中每个位置的查克拉果数量,等于从矩阵第一行第一列的位置走到这个位置的最近路线的方案数乘以 y 。

        已知,hybest进入矩阵时,出现在矩阵第n行,第m列的位置,出口在矩阵的第x行,第x列。请你帮助hybest,拿到最多的查克拉之果。
        请注意,为了尽快拯救文太,hybest只选择跑的最快的路线(即所移动的步数最少)。

输入格式:
        输入一行,五个整数,n,m,x,k,y(0< n,m <= x, 0< x,k <= 1000, 0 < y <= 10)


输出格式:
        输出一个整数单独一行,代表在跑的最快的前提下,hybest可以为文太带来多少查克拉之果。


样例输入​:

        1 1 5 79 1


样例输出​:
        69


题目大意:
                x*x的二维方格里,每个点有一个果子数,为由(1,1)到这个点的方案数*y,问从(n,m)出发,经过最短的路径到达(x,x)并拿走这条路径上的所有果实,得到的最多果实数(最后的果子数要模k)。
解题思路:
               这道题朴素的想法是做一个o(n^3)的dp状态,dp[i][j][k]代表在从入口走到矩阵[i][j]这个位置,身上带着k的果子是否可以达到。由于数据量较大,这么做会超时。
               可以用bitset+位运算优化,每一位的0/1表示是否可达,优化后时间复杂度变为原来的1/32。
               测评机只能开到150M的空间,所以要采用滚动数组来降低空间花费。

#include<stdio.h>
#include<iostream>
#include<bitset>
using namespace std;
bitset<1005> dp[2][1005];
int map[1005][1005];
int main()
{
	int n, m, x, k, y;
	scanf("%d%d%d%d%d", &n, &m, &x, &k, &y);
	map[1][1] = y%k;
	for (int i = 1; i <= x; i++)
		for (int j = 1; j <= x; j++)
			if(i!=1||j!=1)map[i][j] = (map[i - 1][j] + map[i][j - 1])%k;
	dp[(n-1) % 2][m][0] = 1;
	for (int i = n; i <= x; i++)
		for (int j = m; j <= x; j++)
		{
			dp[i % 2][j] = (dp[!(i % 2)][j] | dp[i%2][j-1]);
			dp[i % 2][j] = ((dp[i % 2][j] << map[i][j]) | (dp[i % 2][j] >> (k - map[i][j])));
			//cout << i << ' ' << j << ' ' << dp[i % 2][j] << endl;
		}
	for (int i = k-1; i >= 0; i--)
	{
		if (dp[x % 2][x][i] == 1)
		{
			printf("%d\n", i);
			break;
		}
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值