牛客小白月赛88--->我不是大富翁

本文介绍了一个使用动态规划方法解决的问题,通过在一维数组中存储状态,描述了如何映射初始位置并实现状态转移方程,以及如何优化代码以减少空间复杂度。最后展示了两种代码实现,一种是二维数组,另一种是一维数组优化版本。
摘要由CSDN通过智能技术生成

一,思路:

1.首先映射一下,将在1的位置上,表示映射成在0位置上(便于后面取余判断位置操作),然后 dp思路,用f[i][j]状态数组,表示表示在第 i 步的时候, j 这个位置是那一步走过来的(其实如果你你真正理解这题的话,除了是由 f [i -1] [ j ],这个状态转移过来的外,其他的都是 0)。

2.状态转移方程:(1)f[i][(j+x)%n]=i,(2)f[i][((j-x)%n+n)%n]=i;

3.具体看代码注释

二,代码:

#include<iostream>
using namespace std;
 
const int N=5010;
int f[N][N];
 
int main(){
     
    int n,m;
    cin>>n>>m;
     
    int x;
    cin>>x;
    
//初始化第一步走之后的状态变化
    f[1][x%n]=1;
    f[1][(-x%n+n)%n]=1;
     
    for(int i=2;i<=m;i++){
 
//输入操作步数        
        cin>>x;
        
// 遍历(0,n-1)所有位置,看有没有那个点是上一一步,更新过来的
//(题目要求,必须一个操作一个操作的执行)

        for(int j=0;j<n;j++){

//判断我这一步,能否从 j 这个点,走 x步。
             
            if(f[i-1][j]==i-1){
                f[i][(j+x)%n]=i;
                f[i][((j-x)%n+n)%n]=i;
            }
        }
         
    }
    
//判断在第m步操作后,0这个是否是,第m次操作后更新过来的(只看结果,不看过程)

    if(f[m][0]==m) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}

三,很明显的发现,其实我们每次更新只用到了上一层数组的值,所以我们有可以优化成一维的机会,但是你会发现更新成一维后,我们进行状态转移会影响到我们一些未更新的点或以更新的点,所以我们可以准备两个数组 a , b,一个表示上一步操作后的状态,一个表示这次状态转移后的状态。

四,代码:

#include<iostream>
#include<cstring>
using namespace std;
 
const int N=5010;
int a[N];
int b[N];
 
int main(){
     
    int n,m;
    cin>>n>>m;
     
    int x;
    cin>>x;
     
    a[x%n]=1;
    a[(-x%n+n)%n]=1;
     
    for(int i=2;i<=m;i++){
         
        cin>>x;
         
        for(int j=0;j<n;j++){
             
            if(a[j]==i-1){
                b[(j+x)%n]=i;
                b[((j-x)%n+n)%n]=i;
            }
        }
       
//保存这次状态转移后的状态  
        memcpy(a,b,sizeof a);
    }
     
    if(a[0]==m) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}

  • 25
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值