1. 程式人生 > >POJ 1159 DP+滾動陣列

POJ 1159 DP+滾動陣列

Palindrome
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 57568 Accepted: 19962
Description

A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome.

As an example, by inserting 2 characters, the string “Ab3bd” can be transformed into a palindrome (“dAb3bAd” or “Adb3bdA”). However, inserting fewer than 2 characters does not produce a palindrome.
Input

Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from ‘A’ to ‘Z’, lowercase letters from ‘a’ to ‘z’ and digits from ‘0’ to ‘9’. Uppercase and lowercase letters are to be considered distinct.
Output

Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.
Sample Input

5
Ab3bd
Sample Output

2

題意:
有一個字串。要求問最少新增幾個數使得它是一個迴文串
題解:
觀察後可以發現,這個就是將字串倒置後與原串求最大公共子列的長度,然後n-公共子列長度就是需要新增字元的個數。馬上就寫了一個最長子序列的dp,結果交上去一直超記憶體。 。後來才反應過來用滾動陣列優化記憶體。這個滾動陣列有兩行,old表示之前求得的那一行結果,now表示現在正在遞推的一行。然後操作完一行後對old和now進行異或操作。就把old和now的值換了一下。這樣陣列就是dp[2][5010],就不會超記憶體了。PS:這題用short int也能過。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define F(i,a,b) for(int i = a;i<=b;i++)
#define FI(i,a,b) for(int i = a;i>=b;i--)
#define SIZE 5000+10

using namespace std;

int dp[2][SIZE];
char a[SIZE];

int solve(int n){
    int old = 0,now = 1;
    memset(dp,0,sizeof(dp));
    F(i,1,n){
        FI(y,n,1){
            int j = n+1-y;
            if(a[i]==a[y]){
                dp[now][j] = dp[old][j-1] + 1;
            }else{
                dp[now][j] = max(dp[old][j],dp[now][j-1]);
            }
        }
        now^=1;
        old^=1;
    }
    return dp[old][n];
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        getchar();
        F(i,1,n){
            char c = getchar();
            a[i] = c;
        }
        getchar();
        printf("%d\n",n-solve(n));
    }


    return 0;
}

相關推薦

POJ 1159 DP+滾動陣列

Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 57568 Accepted: 19962 Description A palindrom

POJ-3666 Making the Grade 【動態規劃DP+滾動陣列

題目傳送門 題目:輸入n個數,第i個數字的值為a[i],把第i個數變為j的代價為a[i]-j的絕對值,求把這n個數組成的數列變成單調數列的最小代價。 題解:dp[i][j]表示前i個數最大值為b[j]時的最小代價,即第i個數在總數列中的值為第j小的時候的最小代價。 動態轉移方程:dp

【Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) D. Minimum path】dp+滾動陣列

D. Minimum path 題意 給你一個字元矩陣,起點在左上角,每次可以向右或者向下走,可以改變這個字元矩陣中的k個字元,是這個路徑構成的字串字典序最小。 做法 由於可以改變k個字元,那麼肯定是找到一條路徑,前面至少有k項為a, 後面按照字典序選擇路徑就可以。 所

HDU 1024 簡單dp 滾動陣列

  要求:n個正陣列成的序列,整數範圍-32768 ≤ S ≤ 32767,1 ≤ n ≤ 1,000,000,挑出m個無交集的連續子序列使這些序列和最大,並輸出最大值。 方法:二維dp、滾動陣列降維。 1.dp[i][j]表示第一個數到下標為j的數挑出i個連續子序列組成的最大

poj1159 Palindrome (簡單dp&&滾動陣列

連結: 題意: 至少增添多少個字元可以使原字串變成迴文串 思路: 原字串反轉,求最長公共子序列長度,剩餘的長度就是需要加的字元數 這裡用到了滾動陣列,因為該次的dp其實只取決去前一次的dp

牛客訓練賽36 B題(dp滾動陣列)

2019年第一次比賽,遭逢大敗。。。都不忍心看自己的排名,第一題一直在想該怎麼去優化。發現並不用,直接暴力過。。。心態炸了,第二題是dp題,一開始想到了增加維度以獲得更多資訊,還好死不死的用疲勞度作為第二維。。。結果陣列變成400*81000那麼大。。。一直在推狀態轉移方程還推不出來。。。看了題

HDU4427Math Magic (dp+滾動陣列)

題目連結: 題意: 求選定k個數,k個數的和為n,最小公倍數是m的方案數,最後的結果mod 1000000007; 分析: 狀態轉移很好找,難的是自己去實現優化。 狀態轉移方程為 : dp[i+

hihocoder#1044狀態壓縮dp+滾動陣列

//20ms 0#include<iostream> #include <string.h> #include <stdio.h> using namespace std; #define MAXN 1500 int N,M,Q; i

LeetCode--Best Time to Buy and Sell Stock IV(DP + 滾動陣列

題意:已知第1天、第2天......第N天的股票價格,每天只能進行一次買或者賣,且規定手裡的股票賣出之前不能買進新的股票,問在最多進行K次交易的情況下,採用最優方案淨利潤能有多少。 分析: 1、設j天完成不超過i次交易能得到的最大收益是f(i,j),顯然f(0,0) =

noip 2015 子串(dp+滾動陣列)

 題目大意:給定兩個字串A,B(都是由a,b組成)(長度分別為n,m);你可以在字串A中任擷取k個字串按擷取順序組成字串B,問能擷取的方案數 動態規劃; s[i][j][k]:字串A正要處理第i項了,陣列B匹配正要第j項,已經截取了k個字串,總方案數; f[i][j][

HDU 4576(概率DP+滾動陣列

Michael has a telecontrol robot. One day he put the robot on a loop with n cells. The cells are numbered from 1 to n clockwise.  At first the robot is i

Playing games —— 基本dp+滾動陣列

題目描述 Niuniu likes playing games. He has n piles of stones. The i-th pile has ai stones. He wants to play with his good friend,

POJ1159迴文字串(DP+滾動陣列

題目的大概意思就是給你一個字串,讓你在任意位置新增任意字元讓它變成一個迴文字串,求最少新增的字元數。 這是一道典型的DP,總體思路就是把逆串搞出來,兩個字串求出一個最大公共子序列的長度,然後拿n減去這

最大子段-n上找m個子段的和為最大-動態規劃-二維dp+滾動陣列dp優化

1.二維dp dp[i][j]代表的是j長度上找到i段,使得i段和最大。(其中最後一段的最後一位一定要是a[j],這句話不理解的可以看看http://blog.csdn.net/qq_36523667/article/details/78598426) 這時最後一段分為兩

1024 Max Sum Plus Plus(DP + 滾動陣列

題目大意:求m個不相交區間的最大和 解題思路:這題是參考別人的,傳送門 再自己組織一下,用dp[i][j]表示前j個數組組成了i個不相交區間的最大和,其中第j個數字一定在某個區間內 那現在要決策的是,第j個數組是在和別的陣列成了一個區間,還是自己獨立成了一

poj 1159】 Palindrome DP(類最長公共子序列)+滾動陣列

Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 58492 Accepted: 20318 Description A palindrom

poj 2663 Tri Tiling (狀壓dp+多米諾骨牌問題+滾動陣列反思)

本來直接一波狀壓dpAC的 #include<cstdio> #include<cstring> #include<algorithm> #define REP(i

poj 1159 Palindrome(最長公共子序列 + 滾動陣列)

http://poj.org/problem?id=1159 題意:給定一個字串,問最少插入多少個字元,使得該字串變成迴文字串。 思路:原字串序列是X,逆序列是Y,則最少需要補充的字母數=X的長度-X

POJ 1159 Palindrome【LCS+滾動陣列】【水題】

Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 63833 Accepted: 22254 Description A palindrome is a symmetr

POJ 1159 Palindrome 最大公共子序列+滾動陣列

題目描述: A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You ar