Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 动态规划问题的自顶向下方法_C++_C++14_Dynamic Programming - Fatal编程技术网

C++ 动态规划问题的自顶向下方法

C++ 动态规划问题的自顶向下方法,c++,c++14,dynamic-programming,C++,C++14,Dynamic Programming,问题就在这里- 您将获得大小为n的数组B。你必须构造一个数组,使1n; memset(dp,-1,sizeof(dp)); ll res=0; 对于(int i=0;i>b[i]; ll s1=solve(0,0,1);//从idx 0标志0开始,值为1 ll s2=solve(0,1,b[0]);//从idx 0标志1开始,值为b[0] 您可以实现一种递归方法。在这里,一个简单的迭代实现可以获得O(n)的时间效率和O(1)的空间效率 (不计算输入数组所需的空间) 您正确地指出,在索引i,我们只

问题就在这里-

您将获得大小为n的数组B。你必须构造一个数组,使1n; memset(dp,-1,sizeof(dp)); ll res=0; 对于(int i=0;i>b[i]; ll s1=solve(0,0,1);//从idx 0标志0开始,值为1 ll s2=solve(0,1,b[0]);//从idx 0标志1开始,值为b[0]
您可以实现一种递归方法。在这里,一个简单的迭代实现可以获得O(n)的时间效率和O(1)的空间效率 (不计算输入数组所需的空间)

您正确地指出,在索引
i
,我们只有两个选择,
a[i]=1
(标志=0)或
a[i]=b[i]
(标志=1)

其基本思想是,当研究在索引
i
上做出什么选择时,我们只需要知道对于flag=0(
sum0
)或flag=1(
sum1
),在索引
i-1
处结束的最佳和是什么

我们不需要明确地计算数组
a[.]

注意:我在代码中保留了
long-long-int
,但似乎
int
在这里已经足够了

#include    <iostream>
#include    <cstdio>
#include    <vector>
#include    <cstdlib>
#include    <algorithm>

#define mod 1000000007          // needed ???

long long int sum_diff (const std::vector<long long> &b) {
    int n = b.size();
    long long int sum0 = 0;
    long long int sum1 = 0;
    for (int i = 1; i < n; ++i) {
        long long int temp = std::max (sum0, sum1 + b[i-1] - 1);            // flag = 0: a[i] = 1
        sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1]));  // flag = 1: a[i] = b[i]
        sum0 = temp;
    }
    return std::max (sum0, sum1);
 }


int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    std::cin >> t;
    while(t--) { 
        int n;
        std::cin >> n;
        std::vector<long long int> b(n);
        for(int i = 0;i < n; i++) std::cin >> b[i];
        long long int s = sum_diff (b);
        std::cout << s << "\n";
    }
}
#包括
#包括
#包括
#包括
#包括
#定义模块100000007//是否需要???
long long int sum_diff(const std::vector&b){
int n=b.size();
长整型sum0=0;
长整型sum1=0;
对于(int i=1;i>t;
而(t--){
int n;
标准:cin>>n;
std::载体b(n);
对于(inti=0;i>b[i];
长整型s=和差(b);
std::cout;
而(t--){
int n,sum0,sum1;
标准:cin>>n;
std::载体b(n);
对于(inti=0;i>b[i];
int s=和差(b);

实际上,我只使用了idx和flag两种状态就找到了解决方案

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;

ll n,k;
ll dp[100002][2];
ll b[100005];

ll solve(ll idx,ll flag)
{
    if(idx>=n-1)
        return 0;
    if(dp[idx][flag]!=-1)
        return dp[idx][flag];
    ll val=(flag==1)?b[idx]:1;
    ll left=solve(idx+1,0)+val-1;
    ll right=solve(idx+1,1)+abs(val-b[idx+1]);
    return (dp[idx][flag]=max(left,right));
}

int main()
{ 
ll t;
cin>>t;
while(t--)
{ 
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
for(int i=0;i<n;i++)
    cin>>b[i];
ll s1=solve(0,0);
ll s2=solve(0,1);
cout<<max(s1,s2)<<"\n";
}
}
#包括
使用名称空间std;
typedef long long int ll;
ll n,k;
律政司司长[100002][2];
llb[100005];
ll solve(ll idx,ll标志)
{
如果(idx>=n-1)
返回0;
如果(dp[idx][flag]!=-1)
返回dp[idx][flag];
ll val=(flag==1)?b[idx]:1;
ll left=solve(idx+1,0)+val-1;
ll right=solve(idx+1,1)+abs(val-b[idx+1]);
返回(dp[idx][flag]=max(左、右));
}
int main()
{ 
LLT;
cin>>t;
而(t--)
{ 
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
对于(int i=0;i>b[i];
ll s1=求解(0,0);
ll s2=求解(0,1);

coutPlease不要将“竞争性”网站用作学习或教学资源,因为它们只会教给你真正的坏习惯,而这些坏习惯永远不会让你就业(或者任何人都想用一根十英尺长的杆子来触碰你的代码)获取,参加课程,学习至少C++的基础知识,以及一些常用的标准算法和数据结构。训练,实验,程序,学习。然后你可以用这些网站作为培训资源。我只是练习它。它有助于编码面试。我猜测这些网站所提倡的风格(你在这里展示)。不适合编写采访的代码。恰恰相反。这就是为什么你不应该作为初学者使用这些网站来学习编程。我知道这可以通过自下而上的方法来完成。但是你能改变我的递归解决方案中的任何内容吗?或者提供另一种自上而下的方法,这将是非常有用的。因为迭代实现很难在第一个注释中进行思考此时,算法仍然是递归的:我从索引
I-1
解得到索引
I
解。一个等价的递归实现(自顶向下)是立即的。请看一看新的代码。两种方法都实现了。好的,这很有帮助。我会接受你的回答。你能想办法改变我的自上而下的方法,这样它就不会依赖于任何一个州吗?或者这是不可能的
#include    <iostream>
#include    <cstdio>
#include    <cstdlib>
#include    <vector>
#include    <algorithm>

int sum_diff (const std::vector<int> &b) {
    int n = b.size();
    int sum0 = 0;
    int sum1 = 0;
    for (int i = 1; i < n; ++i) {
        int temp = std::max (sum0, sum1 + b[i-1] - 1);                      // flag = 0: a[i] = 1
        sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1]));  // flag = 1: a[i] = b[i]
        sum0 = temp;
    }
    return std::max (sum0, sum1);
 }

 void sum_diff_recurs (const std::vector<int> &b, int i, int&sum0, int &sum1) {
    if (i == 0) {
        sum0 = sum1 = 0;
        return;
    }
    sum_diff_recurs (b, i-1, sum0, sum1);
    int temp = std::max (sum0, sum1 + b[i-1] - 1);                      // flag = 0: a[i] = 1
    sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1]));  // flag = 1: a[i] = b[i]
    sum0 = temp;
 }

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    std::cin >> t;
    while(t--) { 
        int n, sum0, sum1;
        std::cin >> n;
        std::vector<int> b(n);
        for(int i = 0; i < n; i++) std::cin >> b[i];
        int s = sum_diff (b);
        std::cout << s << "\n";
        sum_diff_recurs (b, n-1, sum0, sum1);
        std::cout << std::max(sum0, sum1) << "\n";
    }
}
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;

ll n,k;
ll dp[100002][2];
ll b[100005];

ll solve(ll idx,ll flag)
{
    if(idx>=n-1)
        return 0;
    if(dp[idx][flag]!=-1)
        return dp[idx][flag];
    ll val=(flag==1)?b[idx]:1;
    ll left=solve(idx+1,0)+val-1;
    ll right=solve(idx+1,1)+abs(val-b[idx+1]);
    return (dp[idx][flag]=max(left,right));
}

int main()
{ 
ll t;
cin>>t;
while(t--)
{ 
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
for(int i=0;i<n;i++)
    cin>>b[i];
ll s1=solve(0,0);
ll s2=solve(0,1);
cout<<max(s1,s2)<<"\n";
}
}