暑假训练-训练8 区间DP

A - 石子归并
Time Limit:1000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu
Submit

Status
Description
现在有n堆石子,第i堆有ai个石子。现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数。求合并所有石子的最小代价。

Input
第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个整数n(2<=n<=100),表示石子的堆数。
第二行包含n个正整数ai(ai<=100),表示每堆石子的石子数。

Output
每组数据仅一行,表示最小合并代价。

Sample Input
2
4
1 2 3 4
5
3 5 2 1 4
Sample Output
19
33

A:
F[i][j]表示在[i,j]上的最优解

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
const int INF=99999999;
int A[MAX],sum[MAX],F[MAX][MAX];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        memset(sum,0,sizeof(sum));
        memset(F,0,sizeof(F));
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&A[i]);
            sum[i]=sum[i-1]+A[i];
        }
        for (int l=2;l<=n;l++)
        {
            for (int i=1;i<=n-l+1;i++)
            {
                int j=i+l-1;
                F[i][j]=INF;
                for (int k=i;k<j;k++)
                {
                    F[i][j]=min(F[i][j],F[i][k]+F[k+1][j]+sum[j]-sum[i-1]);
                    //cout<<"F["<<i<<"]["<<j<<"]="<<F[i][j]<<endl;
                }
            }
        }
        printf("%d\n",F[1][n]);
    }
    return 0;
}

B - Brackets
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit

Status
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




B:
F[i][j]表示[i,j]范围内的合法数

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
const int INF=99999999;
int F[MAX][MAX];
int main()
{
    string s;
    while(cin>>s&&s[0]!='e')
    {
        int len=s.length();
        s.insert(0,1,' ');
        memset(F,0,sizeof(F));
        for (int l=2;l<=len;l++)
        {
            for (int i=1;i<=len-l+1;i++)
            {
                int j=i+l-1;
                if ((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']'))
                    F[i][j]=F[i+1][j-1]+2;
                for (int k=i;k<j;k++)
                {
                    F[i][j]=max(F[i][j],F[i][k]+F[k+1][j]);
                }
            }
        }
        cout<<F[1][len]<<endl;
    }
    return 0;
}

C - Halloween Costumes
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit

Status
Description
Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning to attend as many parties as he can. Since it’s Halloween, these parties are all costume parties, Gappu always selects his costumes in such a way that it blends with his friends, that is, when he is attending the party, arranged by his comic-book-fan friends, he will go with the costume of Superman, but when the party is arranged contest-buddies, he would go with the costume of ‘Chinese Postman’.

Since he is going to attend a number of parties on the Halloween night, and wear costumes accordingly, he will be changing his costumes a number of times. So, to make things a little easier, he may put on costumes one over another (that is he may wear the uniform for the postman, over the superman costume). Before each party he can take off some of the costumes, or wear a new one. That is, if he is wearing the Postman uniform over the Superman costume, and wants to go to a party in Superman costume, he can take off the Postman uniform, or he can wear a new Superman uniform. But, keep in mind that, Gappu doesn’t like to wear dresses without cleaning them first, so, after taking off the Postman uniform, he cannot use that again in the Halloween night, if he needs the Postman costume again, he will have to use a new one. He can take off any number of costumes, and if he takes off k of the costumes, that will be the last k ones (e.g. if he wears costume A before costume B, to take off A, first he has to remove B).

Given the parties and the costumes, find the minimum number of costumes Gappu will need in the Halloween night.

Input
Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case starts with a line containing an integer N (1 ≤ N ≤ 100) denoting the number of parties. Next line contains N integers, where the ith integer ci (1 ≤ ci ≤ 100) denotes the costume he will be wearing in party i. He will attend party 1 first, then party 2, and so on.

Output
For each case, print the case number and the minimum number of required costumes.

Sample Input
2
4
1 2 1 2
7
1 2 1 1 3 2 1
Sample Output
Case 1: 3
Case 2: 4


C: F[i][j]表示在区间[i,j]内需要的最小衣服数量.首先初始化为j-i+1(最大值),F[i][j]=F[i+1][j]+1;
   F[i][j]=min(F[i][j],F[i+1][k-1]+F[k][j]) 找到与第i个相同的(k),分解成两个子问题.

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
const int INF=99999999;
int T,N,A[MAX],F[MAX][MAX];
int main()
{
    cin>>T;
    for (int a=1;a<=T;a++)
    {
        memset(F,0,sizeof(F));
        cin>>N;
        for (int i=1;i<=N;i++)
        {
            cin>>A[i];
        }
        for (int i=1;i<=N;i++)
            for (int j=i;j<=N;j++)
                F[i][j]=j-i+1;
        for (int l=2;l<=N;l++)
        {
            for (int i=N-l+1;i>=1;i--)
            {
                int j=i+l-1;
                F[i][j]=F[i+1][j]+1;
                for (int k=i+1;k<=j;k++)
                {
                    if (A[k]==A[i])
                    {
                        F[i][j]=min(F[i][j],F[i+1][k-1]+F[k][j]);
                    }
                }
            }
        }
        cout<<"Case "<<a<<": "<<F[1][N]<<endl;
    }
    return 0;
}

D - You Are the One
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
  The TV shows such as You Are the One has been very popular. In order to meet the need of boys who are still single, TJUT hold the show itself. The show is hold in the Small hall, so it attract a lot of boys and girls. Now there are n boys enrolling in. At the beginning, the n boys stand in a row and go to the stage one by one. However, the director suddenly knows that very boy has a value of diaosi D, if the boy is k-th one go to the stage, the unhappiness of him will be (k-1)*D, because he has to wait for (k-1) people. Luckily, there is a dark room in the Small hall, so the director can put the boy into the dark room temporarily and let the boys behind his go to stage before him. For the dark room is very narrow, the boy who first get into dark room has to leave last. The director wants to change the order of boys by the dark room, so the summary of unhappiness will be least. Can you help him?
Input
  The first line contains a single integer T, the number of test cases. For each case, the first line is n (0 < n <= 100)
  The next n line are n integer D1-Dn means the value of diaosi of boys (0 <= Di <= 100)
Output
  For each test case, output the least summary of unhappiness .
Sample Input
2
  
5
1
2
3
4
5

5
5
4
3
2
2
Sample Output
Case #1: 20
Case #2: 24



D: F[i][j]表示在区间[i,j]中的最小值 小黑屋是一个栈 假设i第k个上场 则分解为F[i+1][i+k-1]和F[i+k][j]

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
const int INF=99999999;
int T,N,A[MAX],F[MAX][MAX],SUM[MAX];
int main()
{
    cin>>T;
    for (int a=1;a<=T;a++)
    {
        memset(F,0,sizeof(F));
        memset(SUM,0,sizeof(SUM));
        cin>>N;
        for (int i=1;i<=N;i++)
        {
            cin>>A[i];
            SUM[i]=SUM[i-1]+A[i];
        }
        for (int l=2;l<=N;l++)
        {
            for (int i=1;i<=N-l+1;i++)
            {
                int j=i+l-1;
                F[i][j]=INF;
                for (int k=1;k<=j-i+1;k++)
                {
                    F[i][j]=min(F[i][j],F[i+1][i+k-1]+(k-1)*A[i]+F[i+k][j]+k*(SUM[j]-SUM[i+k-1]));
                }
            }
        }
        cout<<"Case #"<<a<<": "<<F[1][N]<<endl;
    }
    return 0;
}

E - Multiplication Puzzle
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit

Status
Description
The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the product of the number on the card taken and the numbers on the cards on the left and on the right of it. It is not allowed to take out the first and the last card in the row. After the final move, only two cards are left in the row.

The goal is to take cards in such order as to minimize the total number of scored points.

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
10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000

If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be
1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150.
Input
The first line of the input contains the number of cards N (3 <= N <= 100). The second line contains N integers in the range from 1 to 100, separated by spaces.
Output
Output must contain a single integer - the minimal score.
Sample Input
6
10 1 50 50 20 5
Sample Output
3650


E:
F[i][j]表示在[i,j)区间的最优解

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=105;
const int INF=99999999;
int A[MAX],F[MAX][MAX];
bool used[MAX];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(F,0,sizeof(F));
        for (int i=0;i<MAX;i++)
            used[i]=false;
        for (int i=1;i<=n;i++)
            scanf("%d",&A[i]);
        for (int l=2;l<=n-1;l++)
        {
            for (int i=2;i<=n-l+1;i++)
            {
                int j=i+l-1;
                F[i][j]=INF;
                for (int k=i;k<j;k++)
                {
                    F[i][j]=min(F[i][j],F[i][k]+F[k+1][j]+A[i-1]*A[k]*A[j]);
                    //cout<<"F["<<i<<"]["<<j<<"]="<<F[i][j]<<endl;
                }
            }
        }
        cout<<F[2][n]<<endl;
    }
    return 0;
}

F - Running
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit

Status
Description
The cows are trying to become better athletes, so Bessie is running on a track for exactly N (1 ≤ N ≤ 10,000) minutes. During each minute, she can choose to either run or rest for the whole minute.

The ultimate distance Bessie runs, though, depends on her ‘exhaustion factor’, which starts at 0. When she chooses to run in minute i, she will run exactly a distance of Di (1 ≤ Di ≤ 1,000) and her exhaustion factor will increase by 1 – but must never be allowed to exceed M (1 ≤ M ≤ 500). If she chooses to rest, her exhaustion factor will decrease by 1 for each minute she rests. She cannot commence running again until her exhaustion factor reaches 0. At that point, she can choose to run or rest.

At the end of the N minute workout, Bessie’s exaustion factor must be exactly 0, or she will not have enough energy left for the rest of the day.

Find the maximal distance Bessie can run.

Input
* Line 1: Two space-separated integers: N and M
* Lines 2..N+1: Line i+1 contains the single integer: Di

Output
* Line 1: A single integer representing the largest distance Bessie can run while satisfying the conditions.
 

Sample Input
5 2
5
3
4
2
10
Sample Output
9


F:



#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
const int MAX=10005;
const int INF=99999999;
int A[MAX],F[MAX][505]; //F[i][j] 第i分钟疲劳值为j时的最大距离
int N,M;
int main()
{
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        memset(F,0,sizeof(F));
        for (int i=1;i<=N;i++)
            scanf("%d",&A[i]);
        for (int i=1;i<=N;i++)
        {
            for (int j=1;j<=M&&j<=i;j++)
                F[i][j]=F[i-1][j-1]+A[i];
            F[i][0]=F[i-1][0];
            for (int j=1;j<=M&&i-j>=0;j++)
                F[i][0]=max(F[i-j][j],F[i][0]);
        }
        cout<<F[N][0]<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值