leetcode 564,546

564 Find the Closest Palindrome:给出一个长度不超过18的非负整数,求出与其最近接的回文整数(不包括它自己)。

思路:假设其长度为偶数。将其分为两半,前一半设为$x$,那么最后的答案的前一部分一定是$x-1,x,x+1$三个中的一个。在这里,$x-1$有可能变成少一位的数字,比如100到99; $x+1$可能多一位,比如99到100.长度为奇数时类似的思路。

long long strToInt(string s) {
    long long t=0;
    for(int i=0;i<(int)s.size();++i) {
        t=t*10+s[i]-‘0‘;
    }
    return t;
}

string intToString(long long x) {
    if(x==0) return "0";
    stack<int> st;
    while(x) {
        st.push(x%10);
        x/=10;
    }
    string s="";
    while(!st.empty()) {
        s+=‘0‘+st.top();
        st.pop();
    }
    return s;
}

void up(long long &x,long long p,long long q) {

    if(p==q) return;

    if(x==-1) {
        x=p;
    }
    else if(abs(p-q)<abs(x-q)) {
        x=p;
    }
}

string revStr(string s) {
    int ll=0,rr=(int)s.size()-1;
    while(ll<rr) {
        swap(s[ll++],s[rr--]);
    }
    return s;
}

class Solution {
public:
    string nearestPalindromic(string s) {

        long long x=strToInt(s);
        int n=(int)s.size();

        if(s.size()==1) {
            if(s=="0") return "1";
            return intToString(x-1);
        }

        long long ans=-1;
        if(n&1) {
            long long t0=strToInt(s.substr(0,n/2+1));

            for(int i=-1;i<=1;++i) {
                string s1=intToString(t0+i);
                string s2=s1;

                revStr(s1.substr(0,s1.size()-(s1.size()==n/2+1)));

                if(s1.size()<n/2+1) {
                    s2+=s1;
                }
                else if(s1.size()==n/2+1) {
                    s2+=revStr(s1.substr(0,n/2));
                }
                else {
                    s2+=revStr(s1.substr(0,s1.size()-2));
                }

                long long k=strToInt(s2);
                up(ans,k,x);
            }
        }
        else {
            long long t0=strToInt(s.substr(0,n>>1));

            if(t0==1) {
                up(ans,9,x);
                up(ans,11,x);
                up(ans,22,x);
                return intToString(ans);
            }

            for(int i=-1;i<=1;++i) {
                string s1=intToString(t0+i);
                string s2=s1;

                if(s1.size()<n/2) {
                    s2+=revStr(s1+"9");
                }
                else if(s1.size()==n/2) {
                    s2+=revStr(s1);
                }
                else {
                    s2+=revStr(s1.substr(0,n/2));
                }

                long long k=strToInt(s2);
                up(ans,k,x);
            }
        }
        return intToString(ans);
    }
};

546 Remove Boxes:给定一个长度不超过100的整数数列。每次可以删除连续的相同的一段(删除后两端的会连接到一起)。设该次删除的数字的个数为$k$,那么将得到$k*k$个分数。选择一种删除的序列,使得删除完所有数字后得到的分数最多?

思路:对于某一段连续的数字,可以将其单独删除,或者是跟其他的连在一起的时候再删除。设$f[L][R][k]$表示现在删除$[L,R]$之间的所有数字,且$R$位置之后有$k$个数字跟$R$位置上的数字相同.如果单独删除$R$以及后面的数字,有分数$f[L][R-1][0]+(1+k)^{2}$;否则可以选择跟之前的某一段合并,设合并的位置为$t$,那么有$f[L][t][k+1]+f[t+1][R-1][0]$。

实际实现的时候可以将连续相同的进行合并,速度会快一些。

vector<pair<int,int>> all;
int f[111][111][111];

int dfs(int L,int R,int k) {
    if(L>R) return 0;
    if(f[L][R][k]!=-1) return f[L][R][k];
    if(L==R) return (k+all[L].second)*(k+all[L].second);
    int &ans=f[L][R][k];
    ans=dfs(L,R-1,0)+(k+all[R].second)*(k+all[R].second);
    for(int i=R-1;i>=L;--i) {
        if(all[i].first==all[R].first) {
            int tmp=dfs(L,i,all[R].second+k)+dfs(i+1,R-1,0);
            ans=max(ans,tmp);
        }
    }
    return ans;
}

class Solution {
public:
    int removeBoxes(vector<int>& a) {
        all.clear();
        int n=(int)a.size();
        if(n==0) return 0;
        all.push_back(make_pair(a[0],1));
        for(int i=1;i<n;++i) {
            if(a[i]==all.back().first) {
                ++all.back().second;
            }
            else {
                all.push_back(make_pair(a[i],1));
            }
        }
        memset(f,-1,sizeof(f));
        return dfs(0,(int)all.size()-1,0);
    }
};

  

时间: 2024-11-16 08:00:59

leetcode 564,546的相关文章

LeetCode 564. Find the Closest Palindrome

原题链接在这里:https://leetcode.com/problems/find-the-closest-palindrome/ 题目: Given an integer n, find the closest integer (not including itself), which is a palindrome. The 'closest' is defined as absolute difference minimized between two integers. Example

LeetCode 564. Find the Closest Palindrome (构造)

题意: 给一个数字n 求离n最近(且不等)的回文串 存在多个答案返回最小的 首先很容易想到 将数字分为两段,如 12345 -> 123/45,然后将后半段根据前面的进行镜像重置 123/45 -> 12321 那,如果数字刚好是回文串,就把前半段-1就好了 但是存在以下例外,就是当前半段 +1 或 -1 就会造成进位 10999 10901-10999 = -98 11011 - 10999 = -12 可以发现是因为9存在的进位,同样0也可能,所以对前半段进行 +1 和 -1 两种处理,然

Java------简单的输入/输出

一.Scanner 类 什么叫 Scanner 类 Scanner 类是 java 中用于用户与计算机进行交互的基本类; 怎么使用 Scanner 类 Scanner 类 存在 java.util 包中,并提供方法供用户使用;重点是要调用 Scanner 中的方法时,必须先创建一个对象(创建对象要用  new 运算符),调用的基本格式: import java.util.*; // 导包 public class Test{ public static void main(String[] ar

leetcode 546. Remove Boxes

Given several boxes with different colors represented by different positive numbers. You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes

第十周 Leetcode 546. Remove Boxes (HARD) 记忆化搜索

Leetcode546 给定一个整数序列,每次删除其中连续相等的子序列,得分为序列长度的平方 求最高得分. dp方程如下: memo[l][r][k] = max(memo[l][r][k], dfs(boxes,memo,l,i,k+1) + dfs(boxes,memo,i+1,r-1,0)); 意思是在序列的l-r部分后接k长度的 r值序列 所能得到的最大得分. 代码很简单 class Solution { public: int removeBoxes(vector<int>&

Leetcode 546.移除盒子

移除盒子 给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色.你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止.每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k*k 个积分.当你将所有盒子都去掉之后,求你能获得的最大积分和. 示例 1:输入: [1, 3, 2, 2, 2, 3, 4, 3, 1] 输出: 23 解释: [1, 3, 2, 2, 2, 3, 4, 3, 1] ----> [1, 3, 3, 4, 3, 1] (

一天三题LeetCode(C++&amp;JAVA)-1~3

转载请注明出处: http://blog.csdn.net/miaoyunzexiaobao 1.      Two Sum https://leetcode.com/problems/two-sum/ 给定一个数组,在其中找两个数,使两个数之和为给定的target.返回这两个数在数组中的位置.两个数字的位置分别用index1和index2表示,要求index1<index2.例: Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1,

LeetCode Problems List 题目汇总

No. Title Level Rate 1 Two Sum Medium 17.70% 2 Add Two Numbers Medium 21.10% 3 Longest Substring Without Repeating Characters Medium 20.60% 4 Median of Two Sorted Arrays Hard 17.40% 5 Longest Palindromic Substring Medium 20.70% 6 ZigZag Conversion Ea

程序员进阶之算法练习:LeetCode专场

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由落影发表 前言 LeetCode上的题目是大公司面试常见的算法题,今天的目标是拿下5道算法题: 题目1是基于链表的大数加法,既考察基本数据结构的了解,又考察在处理加法过程中的边界处理: 题目2是求数组出现频率前k大的数字,考察思维能力,代码很短: 题目3是给出从两个数组中选择数字,组成一个最大的数字,考察的是贪心的思想: 前三个都偏向于考察想法,实现的代码都比较简单: 题目4.5是数据结构实现题,也是大部分人比较头疼的题目,因为需