石子合并(一)
-
描述
-
有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
代码
#include<iostream> #include<fstream> #include<cstring> #include<algorithm> #include<stdio.h> using namespace std; const int Max=205; const int INF=1000008; int main(){ int n; while(cin>>n && n!=EOF) { int a[Max]={0}; int sum[Max]={0}; for(int i=1;i<=n;i++) { cin>>a[i]; sum[i]=sum[i-1]+a[i]; } int dp[Max][Max]={0}; int Min=10000; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { dp[j][j+i]=INF; if(i+j>n) break; for(int k=j;k<=j+i;k++) { dp[j][j+i]=min( (dp[j][k]+dp[k+1][j+i]),dp[j][j+i]); } dp[j][j+i]+=sum[j+i]-sum[j-1]; } } cout<<dp[1][n]<<endl; } return 0; }
BracketsTime Limit: 1000MS Memory Limit: 65536K Total Submissions: 8962 Accepted: 4809 Description
We give the following inductive definition of a “regular brackets” sequence:
- the empty sequence is a regular brackets sequence,
- if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
- if a and b are regular brackets sequences, then ab is a regular brackets sequence.
- no other sequence is a regular brackets sequence
For instance, all of the following character sequences are regular brackets sequences:
(), [], (()), ()[], ()[()]
while the following character sequences are not:
(, ], )(, ([)], ([(]
Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1, i2, …, im where 1 ≤ i1 < i2 < … < im ≤ n, ai1ai2 … aim is a regular brackets sequence.
Given the initial sequence
([([]])]
, the longest regular brackets subsequence is[([])]
.Input
The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters
(
,)
,[
, and]
; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.Output
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
Sample Input
((())) ()()() ([]]) )[)( ([][][) end
Sample Output
6 6 4 0 6
code
-
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int Max=108; const int INF=-1; int dp[Max][Max]={0}; int main(){ char str[Max]=""; while(cin>>str && strcmp(str,"end")!=0) { memset(dp,0,sizeof(dp)); int len=strlen(str); for(int i=1;i<len;i++) { for(int j=0;j<len;j++) { if( (j+i)>len ) continue; dp[j][j+i]=INF; if( ( str[j]=='(' && str[i+j]==')' ) || ( str[j]=='[' && str[i+j]==']' ) ) { dp[j][i+j]=dp[j+1][i+j-1]+2; } for(int k=j;k<=j+i;k++) { dp[j][i+j]=max(dp[j][i+j],dp[j][k]+dp[k+1][i+j]); } } } cout<<dp[0][len-1]<<endl; } return 0; }
区间dp在我的理解就是 数组储存的状态就是存放的是一个区间的最优值,他的目的就是从内往外扩,或者从外往内缩,注意的地方
是区间dp的最重要的状态的转移 实质上是由于区间大小变化而造成的 ,也就是第一层循环是区间的大小,可以尝试这样去理解区间dp。
-
-
-
整数划分(四)
时间限制: 1000 ms | 内存限制: 65535 KB难度: 3-
暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷。。亲爱的你能帮帮他吗?
问题是我们经常见到的整数划分,给出两个整数 n , m ,要求在 n 中加入m - 1 个乘号,将n分成m段,求出这m段的最大乘积
-
输入
- 第一行是一个整数T,表示有T组测试数据 接下来T行,每行有两个正整数 n,m ( 1<= n < 10^19, 0 < m <= n的位数); 输出
- 输出每组测试样例结果为一个整数占一行 样例输入
-
2 111 2 1111 2
样例输出
-
11 121
描述
#include<iostream> #include<algorithm> #include<cstring> #include<stdio.h> using namespace std; char str[20]=""; long long hf[50][50]={0}; long long dp[50][50]={0}; long long m; int main(){ freopen("../io/整数划分.in","r",stdin); int T; cin>>T; while(T--) { memset(hf,0,sizeof(hf)); memset(dp,0,sizeof(dp)); m=0; scanf("%s%d",str,&m); for(int i=0;i<strlen(str);i++) { hf[i][i]=str[i]-'0'; for(int j=i;j<strlen(str);j++) { hf[i][j]=hf[i][j-1]*10+(str[j]-'0'); } dp[i][0]=hf[0][i]; } //hf存放从i到j的数字大小 for(int i=1;i<strlen(str);i++) { for(int k=1;k<=i;k++) { for(int l=0;l<i;l++) { dp[i][k]=max(dp[i][k],dp[l][k-1]*hf[l+1][i]); } } } //dp存放从开始到i的数分成k次最大值 cout<<dp[strlen(str)-1][m-1]<<endl; } return 0; }
-
-
-
有多组测试数据,输入到文件结束。