给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
示例 1:
输入: “aacecaaa”
输出: “aaacecaaa”
示例 2:
输入: “abcd”
输出: “dcbabcd”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
把要处理的字符分成回文串和非回文串,再将非回文串逆置加到头部。要注意,已经移动出最长回文串边界的情况,这种情况就需要递归处理了。
代码:
class Solution {
public:
string shortestPalindrome(string s) {
int n = s.size();
int i = 0;
for (int j = n - 1; j >= 0; j--) {
if (s[i] == s[j])
i++;
}
if (i == n)
return s;
string remain_rev = s.substr(i, n);
reverse(remain_rev.begin(), remain_rev.end());
//为什么要递归,因为i可能已经移动出了最长字符串的范围
return remain_rev + shortestPalindrome(s.substr(0, i)) + s.substr(i);//ababbcefbbaba
}
};
力扣这个题和网易的C++笔试题第一个类似,只是一个是在前面插入,一个是在后面插入。
思路:
参考大佬的代码,暴力解。感觉自己对于DFS的理解还是不够深刻啊
代码:
#include
using namespace std;
int a[20];
int suffixSum[20];
int n;
int minLoss;
void dfs(int first, int second, int cost, int index)
{
if (index >= n)
{
if (first == second)
minLoss = min(minLoss, cost);
return;
}
if (first == second)
minLoss = min(minLoss, suffixSum[index] + cost);
if (abs(first - second) > suffixSum[index])
return;
// 给first,给second,扔掉
dfs(first + a[index], second, cost, index + 1);
dfs(first, second + a[index], cost, index + 1);
dfs(first, second, cost + a[index], index + 1);
}
int main(int argc, char const *argv[])
{
int t;
cin >> t;
while (t--)
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
memset(suffixSum, 0, sizeof(suffixSum));
for (int i = n - 1; i >= 0; --i)
suffixSum[i] = suffixSum[i + 1] + a[i];
minLoss = INT32_MAX;
dfs(0, 0, 0, 0);
cout << minLoss << endl;
}
return 0;
}
DP解法:
#include
using namespace std;
#define endl '\n'
typedef long long ll;
typedef pair<ll,ll> P;
const int inf=0xffffffff;
int dp[20][1500005];
int main(){
int T;scanf("%d",&T);
while(T--){
memset(dp,-0x3f,sizeof(dp));
int n;scanf("%d",&n);
vector<int>a(n+1);
int sum=0;
for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum+=a[i];}
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<=sum;j++){
dp[i][j]=dp[i-1][j];
dp[i][j]=max(dp[i][j],max(dp[i-1][j+a[i]]+a[i],dp[i-1][abs(j-a[i])]+a[i]));
}
}
printf("%d\n",sum-dp[n][0]);
}
return 0;
}
思路:
参考别人代码
代码:
#include
#include
#include
#include
using namespace std;
int getMinCost(vector<int>a, vector<int>b) {
vector<int>dp(a.size() + 1);
dp[1] = a[0];
for (int i = 2; i < dp.size(); ++i) {
dp[i] = min(dp[i - 1] + a[i - 1], dp[i - 2] + b[i - 2]);
}
return dp.back();
}
string getTime(int cost) {
int h = 8, m = 0, s = 0;
s = cost % 60;
cost /= 60;
m += cost % 60;
cost /= 60;
h += cost % 24;
bool flag = false;
if (h > 12) {
h -= 12;
flag = true;
}
string sh = to_string(h);
if (sh.size() < 2) sh = "0" + sh;
string sm = to_string(m);
if (sm.size() < 2) sm = "0" + sm;
string ss = to_string(s);
if (ss.size() < 2) ss = "0" + ss;
return sh + ":" + sm + ":" + ss + " " + (flag ? "pm" : "am");
}
int main() {
int m;
cin >> m;
while (m-- > 0) {
int n;
cin >> n;
vector<int>a(n);
vector<int>b(n);
for (int i = 0; i < n; ++i) cin >> a[i];
for (int i = 0; i < n - 1; ++i) cin >> b[i];
int cost = getMinCost(a, b);
cout << getTime(cost) << endl;
}
}
PS: DP真的是需要多多练习啊