Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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++ 如何改进此算法以防止TLE is SPOJ提交?_C++_Algorithm_Data Structures_Dynamic Programming - Fatal编程技术网

C++ 如何改进此算法以防止TLE is SPOJ提交?

C++ 如何改进此算法以防止TLE is SPOJ提交?,c++,algorithm,data-structures,dynamic-programming,C++,Algorithm,Data Structures,Dynamic Programming,我正在尝试解决以下问题: 我用C++(动态编程)在C++中编写了一个解决方案(下面的代码)。但是我得到了TLE(超过了时间限制)。如何优化我的代码 #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<algorithm> #include<cmath> using na

我正在尝试解决以下问题:

我用C++(动态编程)在C++中编写了一个解决方案(下面的代码)。但是我得到了TLE(超过了时间限制)。如何优化我的代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>

using namespace std;
string a,b;
vector<string> v;
int dp[85][85];

void filldp()
{
    for(int i = 0; i <= a.length(); i++)
        dp[i][0] = 0;
    for(int i = 0; i <= b.length(); i++)
        dp[0][i] = 0;   

    for(int i = 1; i <= a.length(); i++)
        for(int j = 1; j<= b.length(); j++)
        if(a[i-1] == b[j-1])
            dp[i][j] = dp[i-1][j-1] + 1;
        else
            dp[i][j] = max(dp[i-1][j], dp[i][j-1]); 
}

vector<string> fillv(int i, int j)
{
    vector<string> returnset;
    if(i == 0 || j == 0)
    {   returnset.push_back("");
        return returnset;
    }

    if(a[i-1] == b[j-1])
        { 
          vector<string> set1 = fillv(i-1,j-1);
          for(int k = 0; k < set1.size(); k++)
          { 
            returnset.push_back(set1[k] + a[i-1]);
         }  
          return returnset;
        }

    else
        {
            if(dp[i][j-1] >= dp[i-1][j])
            {
                vector<string> set1 = fillv(i,j-1);
                returnset.insert(returnset.end(), set1.begin(), set1.end());
            }

            if(dp[i-1][j] >= dp[i][j-1])
            {
                vector<string> set2 = fillv(i-1,j);
                returnset.insert(returnset.end(), set2.begin(), set2.end());
            }

            return returnset;

        }       

}

void output()
{
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    for(int i = 0; i < v.size(); i++)
        cout << v[i] << endl;   
    cout << endl;       
}

int main()
{
    int T;
    cin >> T;

    while(T--)
    {
        memset(dp,-1,sizeof(dp));
        v.clear();
        cin >> a >> b;
        filldp();
        v = fillv(a.length(), b.length());
        output();
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
a、b串;
向量v;
int dp[85][85];;
void filldp()
{
对于(int i=0;i>b;
filldp();
v=填充v(a.长度(),b.长度());
输出();
}
返回0;
}

我的猜测是,有很多数据结构的传递是可以避免的,但我不能确切地指出如何避免。

你做的第一件错误事情是使用cin和cout,它们非常慢。永远不要使用cin和cout进行竞赛编程!我从TLE到AC只是通过将cin/cout更改为scanf/printf。

when您知道答案数的最大大小,最好使用数组而不是向量 因为它比向量快得多。 (“至少有一次这样的旅行,但不超过1000次不同的旅行”)

函数
fillv
在代码中浪费了大量的时间。因为它在运行时获得了大量的空间并将其释放(因为
fillv
函数的本地空间)。最好使用全局答案


为了让输入和输出完成“灰色甘道夫”的回答,如果您喜欢使用cin和cout,最好使用
std::ios::sync_with_stdio(false);
(加快io运行时间),但是printf和scanf要比这快得多。

通过使用
fread()获取输入,可以大大缩短执行时间
fread_unlocked()
(如果您的程序是单线程的)。锁定/解锁输入流一次所需的时间可以忽略不计,因此请忽略此问题

代码如下:

#include <iostream>

int maxio=1000000;
char buf[maxio], *s = buf + maxio;

inline char getc1(void)
{
   if(s >= buf + maxio) { fread_unlocked(buf,sizeof(char),maxio,stdin); s = buf; }
   return *(s++);
}
inline int input()
{
   char t = getc1();
   int n=1,res=0;
   while(t!='-' && !isdigit(t)) t=getc1(); if(t=='-')
   {
      n=-1; t=getc1();
   }
   while(isdigit(t))
   {
     res = 10*res + (t&15);
     t=getc1();
   }
   return res*n;
}
#包括
int maxio=1000000;
字符buf[maxio],*s=buf+maxio;
内联字符getc1(void)
{
如果(s>=buf+maxio){fread_解锁(buf,sizeof(char),maxio,stdin);s=buf;}
返回*(s++);
}
内联int输入()
{
chart=getc1();
int n=1,res=0;
while(t!='-'&&!isdigit(t))t=getc1();if(t=='-'))
{
n=-1;t=getc1();
}
while(isdigit(t))
{
res=10*res+(t&15);
t=getc1();
}
返回res*n;
}
这是在
C++
中实现的。在
C
中,不需要包含
iostream
,函数
isdigit()
是隐式可用的

您可以通过调用
getc1()
将输入作为一个字符流,并通过调用
input()
获取整数输入

使用
fread()
的整个想法是一次获取大量的输入。调用
scanf()/printf()
,在锁定和解锁流时重复占用宝贵的时间,这在单线程程序中是完全冗余的

还要确保
maxio
的值能够使所有输入只在几次“往返”中进行(在这种情况下,最好是一次)。根据需要进行调整。这项技术在编程竞赛中非常有效,可以在执行时间上胜过对手


希望这有帮助!

关于
向量和已知大小:只需调用
向量::保留
即可预分配内存。当然,有时您确实需要堆栈分配内存,所以请使用
std::array
。另一个选项是添加
ios::sync_with_stdio(false)
到你的代码。你能解释一下什么是tle吗?tle是在线法官给你的答案之一。在线法官有一系列问题:你选择一个,编写解决方案,然后发送代码。法官编译解决方案,运行它,向它提供输入数据,并分析你的程序生成的输出数据。然后,它给你答案u答案:AC(意思是接受)意味着你的解决方案没有问题:它编译正确,并计算出正确的答案。TLE意味着你的解决方案太慢:当法官运行它时,它没有在时间限制之前计算出解决方案。你应该试试SPOJ(www.SPOJ.pl)或COJ(COJ.uci.cu)。噢,对不起,忘了提到TLE超出了时间限制。其他常见的判断是WA(错误答案:您的程序没有输出输入数据的正确答案)、CE(编译错误,恕不解释)、MLE(超出内存限制:您的程序使用了太多内存)和PE(演示错误:您的程序输出了正确的数据,但格式错误)。什么是TLE?三个字母的回避?如果您不要求受访者熟悉特定亚文化的术语,您会得到更多/更好的答案。