區間DP 入門經典三道題
#include <cstdio>
#include <iostream>
#include <cstring>
#define sf scanf
#define pf printf
using namespace std;
typedef long long LL;
const int maxn = 205;
/*
題意: N堆石子排成一排 每次可以合併相鄰的兩堆石子 合併的代價是兩堆石子的數量的和
在經過N - 1次合併和,N堆石子合併為一堆石子,問最小的代價是多少
DP[i][j] 表示將第i堆和第j堆合併為一堆的最小花費
那麼DP[i][j] 就可以表示成 DP[i][j] = min{DP[i][k] + DP[k + 1][j] + COST((i ~ k):(k + 1 ~ j))}
*/
const LL INF = 0x3f3f3f3f;
LL DP[maxn][maxn];
LL A[maxn];
LL DPS(int l,int r){
if(DP[l][r] != -1) return DP[l][r];
LL& ans = DP[l][r];
ans = INF;
LL L = 0,R = 0;
for(int i = l;i <= r;++i) R += A[i];
for(int k = l;k < r;++k){
L += A[k],R -= A[k];
ans = min(ans,L + R + DPS(l,k) + DPS(k + 1 ,r));
}
return ans;
}
int main(){
int n;
while( ~sf("%d",&n) ){
for(int i = 0;i < n;++i) sf("%lld",A + i);
memset(DP,-1,sizeof(DP));
for(int i = 0;i < n;++i) DP[i][i] = 0;
DPS(0,n - 1);
pf("%lld\n",DP[0][n - 1]);
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>
#define sf scanf
#define pf printf
using namespace std;
/*
題意:給一個只包含‘[’,‘]’,‘(’,‘)’的字串求在這個字串的一個最長的子串 是一個合法括號字元
DP[i][j] 表示將i 到 j 變為合法字串要刪除的最少字元數
那麼 DP[i][j] = min{DP[i][k] + DP[k + 1][j]};check(s[i],s[j]) DP[i][j] = min(DP[i][j],DP[i + 1][j - 1]);
*/
const int INF = 0x3f3f3f3f;
const int maxn = 105;
int DP[maxn][maxn];
char s[maxn];
int DPS(int l,int r){
if(~DP[l][r]) return DP[l][r];
int& ans = DP[l][r];
ans = INF;
if(s[l] == '(' && s[r] == ')' || s[l] == '[' && s[r] == ']') ans = min(ans,DPS(l + 1,r - 1));
for(int k = l;k < r;++k){
ans = min(ans,DPS(l,k) + DPS(k + 1,r));
}
return ans;
}
int main(){
while(sf("%s",s)){
if(s[0] == 'e') break;
int len = strlen(s);
memset(DP,-1,sizeof(DP));
for(int i = 0;i < len;++i){
DP[i][i] = 1;
DP[i + 1][i] = 0;
}
pf("%d\n",len - DPS(0,len - 1));
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#define sf scanf
#define pf printf
using namespace std;
typedef long long int LL;
/* 分類 區間DP入門題
題意: 要求將一個整數N 劃分成M段 使這M段的乘積最大
現在我們將整數 看作一個由數字組成的字串 那麼
DP[l][r][m] 表示將子串(l - r)劃分成M段的最大乘積的值
那麼DP[l][r][m] max{DP[l][k][p] * DP[k + 1][r][q]} (k >= l ^ k < r ^ (p + q) == m)
*/
const int maxn = 20;
LL DP[maxn][maxn][maxn];
LL G[maxn],F[maxn];
int len;
char s[maxn];
LL DPS(int l,int r,int m){
if(~DP[l][r][m]) return DP[l][r][m];
LL& ans = DP[l][r][m] = 0;
if(r - l + 1 < m) ans = 0;
else if(m == 1){
ans = G[l] / F[r + 1];
}
else for(int k = l;k < r;++k){
for(int p = 1;p <= m;++p){
for(int q = 1;q <= m;++q){
if(p + q == m){
ans = max(ans,DPS(l,k,p) * DPS(k + 1,r,q));
}
}
}
}
// pf("%d %d %d %lld\n",l,r,m,ans);
return ans;
}
int main(){
int T;sf("%d",&T);
while( T-- ){
memset(DP,-1,sizeof(DP));
int n,m;
sf("%s %d",s,&m);
len = n = strlen(s);
F[len] = 1;
G[len] = 0;
for(int i = len - 1;~i;--i) {
F[i] = F[i + 1] * 10;
G[i] = G[i + 1] + (s[i] - '0') * F[i + 1];
}
// pf("%lld\n",G[0] / F[1]);
pf("%lld\n",DPS(0,n - 1,m));
}
return 0;
}
相關推薦
區間DP 入門經典三道題
#include <cstdio> #include <iostream> #include <cstring> #define sf scanf #defi
【51nod 1021】石子歸併(區間dp入門)
1021 石子歸併 基準時間限制:1 秒 空間限制:131072 KB 分值: 20 難度:3級演算法題 收藏 關注 N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將N堆石子合併成一堆的最小代價。
[POJ-1651]Multiplication Puzzle [區間DP 入門]
The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes on
聯想面試智力題,聽說前面三道題必考(有部份解答)
聯想面試智力題,所說前面三道題必考,這個沒有被證實過。不過,當用來完完了沒有什麼不可的。 題目如下: 1、一條繩子,從一頭點燃,全部燒完要耗時1個小時,問如何用這條繩子測出半個小時。 我的答案:假設繩子是鈞勻的,把繩子剪成兩斷,其中一斷燒完,那就是半小時。
java經典50道題之4分解質因數
import java.util.Scanner; /** * 題目:將一個正整數分解質因數。例如:輸入90,打印出90=2*3*3*5。 程式分析:對n進行分解質因數,應先找到一個最小的質數k,然後按下述步驟完成: (1)如果這個質數恰等於n,則說明分解質
區間DP入門之 石子歸併問題 NYOJ 737
分析:要求n個石子歸併,我們根據dp的思想劃分成子問題,先求出每兩個合併的最小代價,然後每三個的最小代價,依次知道n個。 定義狀態dp [ i ] [ j ]為從第i個石子到第j個石子的合併最小代
light oj 1031(區間dp入門)
Description You are playing a two player game. Initially there are n integer numbers in an array
Noip 2017 最簡單的三道題
A了這三道題,就可以穩拿一D了(山東) Day1 T1 雖說是個數論題,打表出結論! #include <cstdio> #include <iostream> #define ll long long using namespa
【DP】區間DP入門
在開始之前我要感謝`y總`,是他精彩的講解才讓我對區間DP有較深的認識。 # 簡介 一般是線性結構上的對區間進行求解最值,計數的動態規劃。大致思路是列舉斷點,然後對斷點兩邊求取最優解,然後進行合併從而得解。 ## 原理 結合模板題(合併石子)講述:https://www.acwing.com/prob
Java經典編程題50道之三十
個數 [] -- ++ 要求 add example system oid 有一個已經排好序的數組。現輸入一個數,要求按原來的規律將它插入數組中。 public class Example30 { public static void main(String[] a
Java經典編程題50道之三十二
out char 輸入 void args pri array int ava 取一個整數a從右端開始的4~7位。 public class Example32 { public static void main(String[] args) { cu
Java經典編程題50道之三十七
static new for length print ati class 個人 經典 有n個人圍成一圈,順序排號。從第一個人開始報數(從1到3報數),凡報到3的人退出圈子,問最後留下的是原來第幾號的那位。 public class Example37 { publ
Java經典編程題50道之三十八
編程 奇數 n) ret ava for 調用函數 args print 編寫一個函數:輸入n為偶數時,調用函數求1/2+1/4+...+1/n;當輸入n為奇數時,調用函數1/1+1/3+...+1/n。 public class Example38 { publi
Java經典編程題50道之三十六
nbsp 移動 編程 move main new for i++ java 有n個整數,使其前面各數順序向後移m個位置,最後m個數變成最前面的m個數。 public class Example36 { public static void main(String[]
經典問題三.【環形區間dp】 項鍊 nyoj 460
問題描述: 思路: 在瞭解了一點區間dp的基礎上,我們知道要從小區間最優化推導到大區間最優化。 那麼這題也是一樣:dp[i][j] 代表區間i,j最優釋放的能量。 遞推式:dp[i][j]
Java經典編程題50道之四
編程題 pub else 整數 正整數分解 clas 因數 stat args 將一個正整數分解質因數。例如:輸入90,打印出90=2*3*3*5。 public class Example04 { public static void main(String[]
Java經典編程題50道之五
n) pub 嵌套 example void out [] args core 利用條件運算符的嵌套來完成此題:學習成績>=90分的同學用A表示,60-89分之間的用B表示,60分以下的用C表示。 public class Example05 { public
Java經典編程題50道之八
其中 println i++ class aaa 一個 bsp pub 個數字 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一個數字。例如2+22+222+2222+22222(此時共有5個數相加),幾個數相加由鍵盤控制。 public class Exa
Java經典編程題50道之七
r++ [] main world else number 字符 英文 ray 輸入一行字符,分別統計出其中英文字母、空格、數字和其它字符的個數。 public class Example07 { public static void main(String[] a
Java經典編程題50道之九
因子 oid 例如 println out count 它的 編程題 num 一個數如果恰好等於它的因子之和,這個數就稱為"完數"。例如6=1+2+3。編程找出1000以內的所有完數。 public class Example09 { public static v