zoukankan      html  css  js  c++  java
  • UVA

    UVA - 10559 Blocks

    题意:消消乐,每次连续相同的可以消除,分数加上长度的平方,问最多可以获得几分全部消完

    题解:

    区间dp + 记忆化搜索

    dp[i][j][k] : (区间 [i,  j] 后面带上一段和 j 颜色相同的且长度为 k )的消消乐最大积分

    1.消最后一段颜色和 j 颜色相同的

    dp[i][j][k] <-- dp[i][j-1][0] + (k+1)^2

    2.对于i <= l < j, 如果 l 和 j 的颜色相同, 那么可以把 [l+1, j-1]消掉, 那么剩下的一段就有 k+1 个和 l 相同的一段了

    dp[i][j][k] <-- dp[i][l][k+1] + dp[l+1][j-1][0]

    答案就是dp[1][n][0],采用记忆化搜索更方便转移

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<string.h>
    using namespace std;
    #define ll long long
    #define mem(a, b) memset(a, b, sizeof(a))
    const int maxn = 1e6 + 10;
    const int INF = 0x3f3f3f3f;
    
    const int N = 205;
    int dp[N][N][N];
    int a[N];
    int dfs(int l, int r, int k) {
        if(l > r) return 0;
        if(l == r) return (k+1)*(k+1);
        if(dp[l][r][k] > 0) return dp[l][r][k];
        dp[l][r][k] = dfs(l, r-1, 0) + (k+1)*(k+1);
        for (int i = l; i < r; i++) {
            if(a[i] == a[r]) {
                dp[l][r][k] = max(dp[l][r][k], dfs(l, i, k+1) +  dfs(i+1, r-1, 0));
            }
        }
        return dp[l][r][k];
    }
    int main() {
        int T, n;
        scanf("%d", &T);
        for(int cs = 1; cs <= T; cs++) {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
            mem(dp, -1);
            printf("Case %d: %d
    ", cs, dfs(1, n, 0));
        }
        return 0;
    }
    View Code

    Vasya and Binary String CodeForces - 1107E

    题意:连续消除一定的相同的可以获得题目所给你的分数,问消除完所有的字符串之后可以获得的最大分数

    题解:和上一题类似,可以使用上一题的转移方程,稍微改一下就好了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<string.h>
    using namespace std;
    #define ll long long
    #define mem(a, b) memset(a, b, sizeof(a))
    const int maxn = 1e2 + 10;
    const int INF = 0x3f3f3f3f;
    
    ll dp[maxn][maxn][maxn];
    string s;
    int a[maxn];
    
    ll dfs(int l,int r,int k)
    {
        if(l > r) return 0;
        if(l == r) return a[k + 1];
        if(dp[l][r][k] > 0) return dp[l][r][k];
        dp[l][r][k] = dfs(l,r - 1,0) + a[k + 1];
        for(int i = l; i < r; i++)
        {
            if(s[i] == s[r])
            {
                dp[l][r][k] = max(dp[l][r][k],dfs(l,i,k + 1) + dfs(i + 1,r - 1,0));
            }
        }
        return dp[l][r][k];
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        cin >> s;
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        memset(dp,-1,sizeof dp);
        //dfs(0,n - 1,0);
        cout << dfs(0,n - 1,0) <<endl;
    }
    View Code
  • 相关阅读:
    表的管理
    子查询
    sql语句
    基本sql语句与oracle函数
    Visual C# 2008+SQL Server 2005 数据库与网络开发6.1.1 报表服务概述
    Visual C# 2008+SQL Server 2005 数据库与网络开发 5.4 小结
    Visual C# 2008+SQL Server 2005 数据库与网络开发5.3.1 日期时间函数
    Visual C# 2008+SQL Server 2005 数据库与网络开发 5.3 函数
    Visual C# 2008+SQL Server 2005 数据库与网络开发第6章 数据报表
    Visual C# 2008+SQL Server 2005 数据库与网络开发5.2.2 GROUP BY
  • 原文地址:https://www.cnblogs.com/smallhester/p/11146790.html
Copyright © 2011-2022 走看看