首页 > 其他分享 > Sending a Sequence Over the Network

Sending a Sequence Over the Network

时间:2022-10-18 18:44:48浏览次数:68  
标签:Sending Network 状态 Over 序列 长度 true ll dp

传送门

题意:
一段a序列,划分他,每一个区间都有一个长度,这个长度可以放在他划分的区间的左侧或者右侧,然后重新构成一个b序列,现在给出b序列,问能否由a序列得来


思路:
首先,去暴力分析,划分的区间数有超复杂度种情况,所以肯定不能去暴力的划分区间,其次,每个区间都是一个一个长度,一段序列, 信息只有这么多了,观察一下,首端和尾端,发现首端的状态,很难判断,但是尾端的状态是很好判断的,尾端的那个状态,最后一个数字,要么是左侧的区间长度,要么是由前面的某个状态得来的,这里有一个转移,可以思考dp了,如果dp[i - b[i] - 1] = true, 说明这个状态是可以的,dp[i] = true, 然后如果不能从这个状态转移过来,那就说明,只能由前面的某一长度转移过来了,初始化dp[0] = true, 因为最后一个状态是肯定只有这两种状态,然后dp转移的过程中已经枚举了所有的情况,所以这个dp是可行的


总结:
如果暴力分析感觉超时间复杂度,可以分解,注意题目给出的条件,观察题目的首尾极端条件即可,线性dp, dp枚举了所以的划分状态

点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);
#define endl '\n'
using namespace std;

typedef long long ll;
const ll MAXN = 2e5 + 10;
ll T, n;
ll b[MAXN];
bool dp[MAXN];

void init()
{
    for (int i = 1; i <= n; ++i)
        dp[i] = false;
}

int main()
{
    IOS; cin.tie(0), cout.tie(0);
    cin >> T;
    while (T--)
    {
        cin >> n;
        init();
        for (int i = 1; i <= n; ++i)
            cin >> b[i];
        dp[0] = true, dp[1] = false;
        for (int i = 1; i <= n; ++i)
        {
            if (i + b[i] <= n && dp[i - 1])  //作为右侧的长度,而且还没有越界
                dp[i + b[i]] = true;
            if (i - b[i] - 1 >= 0 && dp[i - b[i] - 1])  //作为左侧的长度,而且还没有越界
                dp[i] = true;    
        }
        cout << (dp[n] ? "YES" : "NO") << endl;
    }  
    return 0;
}
/*
1
2
1 1
*/

标签:Sending,Network,状态,Over,序列,长度,true,ll,dp
From: https://www.cnblogs.com/jumo-xiao/p/16803648.html

相关文章