矩阵连乘
-
描述
-
himdd有一天闲着无聊,随手拿了一本书,随手翻到一页,上面描述了一个神奇的问题,貌似是一个和矩阵有关的东西。
给出三个矩阵和其行列A1(10*100),A2(100*5),A3(5*50)。现在himdd要算出计算矩阵所要的乘法次数,他发现不同的计算次序,所要的乘法次数也不一样,
如:
(A1*A2)*A3 : 10*100*5+5*10*50=7500;
A1*(A2*A3) : 5*100*50+10*100*50 =75000;
他想知道计算矩阵所要的最少乘法次数是多少,很快一个解法就诞生了,有点小happy~~现在他想问问你是否也能找出一个解法呢?
注意:矩阵不可改变顺序。
-
输入
-
有多组测试数据(<=100),每组表述如下:
第一行,有一个整数n矩阵的个数(1<=n<=100)
接下来有n行
第i行有两整数,r,c表示第i个矩阵的行列;(1<=r,c<=100)
输出
- 输出计算矩阵所要的最少乘法次数。 样例输入
-
3 10 100 100 5 5 50
样例输出
-
7500
-
有多组测试数据(<=100),每组表述如下:
const int Max_N = 108 ;
const int inf = 100000000 ;
int x[Max_N] ;
int dp[Max_N][Max_N] ;
int n ;
int DP(){
int i , j , k , len ;
for(i = 1 ; i <= n ; i++)
dp[i][i] = 0 ;
for(i = 1 ; i + 1 <= n ; i++)
dp[i][i+1] = x[i-1] * x[i] * x[i+1] ;
for(len = 2 ; len <= n ; len++){
for(i = 1 ; i + len <= n ; i++){
j = i + len ;
dp[i][j] = inf ;
for(k = i ; k+1 <= j ; k++)
dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k+1][j] + x[i-1] * x[k] * x[j]) ;
}
}
return dp[1][n] ;
}
石子合并(一)
-
描述
-
有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
-
输入
-
有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
输出
- 输出总代价的最小值,占单独的一行 样例输入
-
3 1 2 3 7 13 7 8 16 21 4 18
样例输出
-
9 239
-
有多组测试数据,输入到文件结束。
const int Max_N = 208 ;
const int inf = 1000000008 ;
char str[Max_N] ;
int dp[Max_N][Max_N] ;
int sum[Max_N] ;
int x[Max_N] ;
int n ;
int DP(){
int i , j , len , k ;
sum[0] = 0 ;
for(i = 1 ; i <= n ; i++){
dp[i][i] = 0 ;
sum[i] = sum[i-1] + x[i] ;
}
for(i = 1 ; i + 1 <= n ; i++)
dp[i][i+1] = x[i] + x[i+1] ;
for(len = 2 ; len <= n ; len++){
for(i = 1 ; i + len <= n ; i++){
j = i + len ;
dp[i][j] = inf ;
for(k = i ; k + 1 <= j ; k++)
dp[i][j] = min(dp[i][j] , sum[j] - sum[i-1] + dp[i][k] + dp[k+1][j]) ;
}
}
return dp[1][n] ;
}
Splits the string
-
描述
-
Hrdv is interested in a string,especially the palindrome string.So he wants some palindrome string.
A sequence of characters is a palindrome if it is the same written forwards and backwards. For example, 'abeba' is a palindrome, but 'abcd' is not.
A partition of a sequence of characters is a list of one or more disjoint non-empty groups of consecutive characters whose concatenation yields the initial sequence. For example, ('race', 'car') is a partition of 'racecar' into two groups.
Given a sequence of characters, we can always create a partition of these characters such that each group in the partition is a palindrome! Given this observation it is natural to ask: what is the minimum number of groups needed for a given string such that every group is a palindrome?
For example:
'racecar' is already a palindrome, therefore it can be partitioned into one group.'fastcar' does not contain any non-trivial palindromes, so it must be partitioned as ('f', 'a', 's', 't', 'c', 'a', 'r').'aaadbccb' can be partitioned as ('aaa', 'd', 'bccb').Input begins with the number n of test cases. Each test case consists of a single line of between 1 and 1000 lowercase letters, with no whitespace within.
-
输入
- Each test case consists of a single line of between 1 and 1000 lowercase letters, with no whitespace within. 输出
- For each test case, output a line containing the minimum number of groups required to partition the input into groups of palindromes. 样例输入
-
racecar fastcar aaadbccb
样例输出
-
1 7 3
const int Max_N = 1008 ;
const int inf = 1008 ;
char str[Max_N] ;
int dp[Max_N][Max_N] ;
int DP(){
int i , j , k , len , L = strlen(str) ;
for(i = 0 ; i < L ; i++)
dp[i][i] = 1 ;
for(i = 0 ; i+1 < L ; i++)
dp[i][i+1] = (str[i]==str[i+1] ? 1 : 2) ;
for(len = 2 ; len < L ; len++){
for(i = 0 ; i + len < L ; i++){
j = i + len ;
dp[i][j] = inf ;
if(str[i] == str[j]){
if(dp[i+1][j-1] == 1)
dp[i][j] = 1 ;
else
dp[i][j] = dp[i+1][j-1] + 2 ;
}
for(k = i ; k + 1 <= j ; k++)
dp[i][j] = min(dp[i][j] , dp[i][k]+dp[k+1][j]) ;
}
}
return dp[0][L-1] ;
}
括号匹配(二)
-
描述
-
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的-
输入
-
第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出
- 对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行 样例输入
-
4 [] ([])[] ((] ([)]
样例输出
-
0 0 3 2
-
第一行输入一个正整数N,表示测试数据组数(N<=10)
const int Max_N = 108 ;
const int inf = 1000000 ;
int dp[Max_N][Max_N] ;
char str[Max_N] ;
int DP(){
int i , j , k , len , L = strlen(str) ;
for(i = 0 ; i < L ; i++)
dp[i][i] = 1 ;
for(i = 0 ; i + 1 < L ; i++){
if(str[i] == '(' && str[i+1] == ')' || str[i] == '[' && str[i+1] == ']')
dp[i][i+1] = 0 ;
else
dp[i][i+1] = 2 ;
}
for(len = 2 ; len < L ; len++){
for(i = 0 ; i + len < L ; i++){
j = i + len ;
dp[i][j] =inf ;
if(str[i] == '(' && str[j] == ')' || str[i] == '[' && str[j] == ']')
dp[i][j] = min(dp[i][j] , dp[i+1][j-1]) ;
for(k = i ; k + 1 <= j ; k++)
dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k+1][j]) ;
}
}
return dp[0][L-1] ;
}
删数游戏:
For example, if cards in the row contain numbers 10 1 50 20 5, player might take a card with 1, then 20 and 50, scoring
If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be
dp[i][j] 表示开区间(i , j)取完的最小加权和。
const int Max_N = 108 ;
const int inf = 100000000 ;
int x[Max_N] ;
int dp[Max_N][Max_N] ;
int n ;
int DP(){
int i , j , k , len ;
for(i = 1 ; i + 2 <= n ; i++)
dp[i][i+2] = x[i] * x[i+1] * x[i+2] ;
for(len = 3 ; len <= n ; len++){
for(i = 1 ; i + len <= n ; i++){
j = i + len ;
dp[i][j] = inf ;
for(k = i+1 ; k + 1 <= j ; k++)
dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k][j] + x[i]*x[k]*x[j]) ;
}
}
return dp[1][n] ;
}
回文字符串
-
描述
-
所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。
-
输入
-
第一行给出整数N(0<N<100)
接下来的N行,每行一个字符串,每个字符串长度不超过1000.
输出
- 每行输出所需添加的最少字符数 样例输入
-
1 Ab3bd
样例输出
-
2
-
第一行给出整数N(0<N<100)
const int Max_N = 1008 ;
int dp[Max_N][Max_N] ;
char str[Max_N] ;
int DP(){
int i, j , k , len , L = strlen(str) ;
for(i = 0 ; i < L ; i++)
dp[i][i] = 0 ;
for(i = 0 ; i+1 < L ; i++)
dp[i][i+1] = (str[i] == str[i+1] ? 0 : 1) ;
for(len = 2 ; len < L ; len++){
for(i = 0 ; i + len < L ; i++){
j = i + len ;
dp[i][j] = j - i + 1 ;
if(str[i] == str[j])
dp[i][j] = min(dp[i][j] , dp[i+1][j-1]) ;
dp[i][j] = min(dp[i+1][j] + 1 , dp[i][j]) ;
dp[i][j] = min(dp[i][j-1] + 1 , dp[i][j]) ;
}
}
return dp[0][L-1] ;
}