【发布时间】:2026-02-06 12:05:02
【问题描述】:
我试图在 codechef 上解决 Reduce String 问题 给出一个长度为 l 的字符串 s 和一个包含 n 个样本字符串的集合 S。我们确实通过这种方式使用集合 S 减少字符串 s: 只要 Si 作为字符串 s 的连续子字符串出现,您可以删除(或不删除)它。 每次删除后,将被删除子串的左右部分连接起来,得到一个新的字符串s。
我写了一个递归函数如下:- 基本上我在我的代码中所做的是要么不删除字符,要么如果它是任何子字符串的一部分则将其删除,但它给出了错误的答案。
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
【问题讨论】:
-
你应该永远
#include <bits/stdc++.h>。它不是正确的 C++。它破坏了便携性并养成了糟糕的习惯。见Why should I not#include <bits/stdc++.h>。另外,请尽量避免使用using namespace std;,因为它是considered bad practice? 您是否尝试过通过调试器运行您的代码?您应该识别有问题的代码并发布重现问题所需的最少代码。请参阅minimal reproducible example 了解更多信息。 -
为什么你认为对字符串长度的动态规划是有效的?如果您的删除字符串是 'a' 和 'b',并且字符串是 'aaaabb',则有一大堆可能的 4 个长字符串,而这 4 个可能的长字符串在变短的方式上都不同。跨度>
-
另外,如果您要编写动态编程解决方案,最好在编写任何代码之前确保您的计划在纸上有效。否则你只会用无效的解决方案陷入困境。
-
这是我第一次看到
signed main():) -
@PaulMcKenzie 是的,您是对的,代码错误:/。但是我已经添加了答案,为什么我的代码在问题中是错误的,什么是正确的代码。谢谢您的帮助。
标签: c++ string dynamic-programming