小白算法练习 dp练习001-区间dp NYOJ 石子合并,整数划分 POJ Brackets

来源:互联网 发布:匡恩网络最新消息 知乎 编辑:程序博客网 时间:2024/05/17 08:02

石子合并(一)

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
描述
    有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
输入
有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
输出
输出总代价的最小值,占单独的一行
样例输入
31 2 3713 7 8 16 21 4 18

样例输出

9239

代码

#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;} 

Brackets
Time Limit: 1000MS Memory Limit: 65536KTotal 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 i1i2, …, im where 1 ≤ i1 < i2 < … < im ≤ nai1ai2 … 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

66406
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的位数);
输出
输出每组测试样例结果为一个整数占一行
样例输入
2111 21111 2
样例输出
11121
#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;
原创粉丝点击