zoukankan      html  css  js  c++  java
  • 区间dp

    POJ2955  子串括号匹配

    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

    6
    6
    4
    0
    6
    //#include <bits/stdc++.h>
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <cmath>
    #include <set>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    string str;
    int dp[105][105];
    
    int main()
    {
        while(cin >> str && str != "end"){
            memset(dp, 0, sizeof(dp));
            int len = str.length();
            for(int i = 1; i <len; i++){
                for(int j = 0, k = i; k < len; j++, k++){
                    if(str[j] == '(' && str[k] == ')' || str[j] =='[' && str[k] ==']'){
                        dp[j][k] = dp[j + 1][k - 1] + 2;//最外围的两个匹配
                    }
                    for(int pos = j; pos < k; pos++){
                        dp[j][k] = max(dp[j][k], dp[j][pos] + dp[pos][k]);//最外围两个不匹配
                    }
                }
            }
            cout<< dp[0][len - 1]<< endl;
        }
        return 0;
    }
    

    POJ1651

    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

    矩阵乘法  通过结合律,矩阵乘法可以大大加快

    //#include <bits/stdc++.h>
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <cmath>
    #include <set>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int n, num[105], dp[105][105];
    
    int main()
    {
        while(scanf("%d",&n) != EOF){
            for(int i = 1; i <= n; i++){
                scanf("%d",&num[i]);
            }
            memset(dp, 0, sizeof(dp));
            //dp[i][j]把第i到j - 1的卡片取走时的结果
            for(int l = 1; l < n - 1; l++){
                for(int i = 2; i + l <= n; i++){
                    int j = i + l;
                    dp[i][j] = inf;
                    for(int k = i; k < j; k++){
                        dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + num[i - 1] * num[k] * num[j]);
                    }
                }
            }
            cout<<dp[2][n] <<endl;
        }
        return 0;
    }
    





  • 相关阅读:
    WPF程序设计 :第四章 按钮与其他控件(Buttons and Other Controls)
    C#参考 : 枚举类型
    C#3.0 新特性学习笔记(3):匿名类型
    F#语言2008年9月CTP版已经更新
    C#3.0 新特性学习笔记(1): 对象集合初始化器
    WPF程序设计基础:属性系统
    C#3.0 新特性学习笔记(2):var 隐式声明变量
    MSSql行列转换的Sql语法 详解与实例
    WPF程序设计 :第一章 应用程序和窗口(The Application and the Window)
    WPF程序设计 :第二章 基本画刷(Basic Brushes)
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643449.html
Copyright © 2011-2022 走看看