zoukankan      html  css  js  c++  java
  • HDU-5900 QSC and Master

    题目大意:

    有n对二元组(key, value),两个相邻的元组间如果key的不互质,那么可以被移除,并获得两个元组的value值之和的分数,问你最多能有多少分数。

    解题思路:

    区间DP

    按照最裸的区间DP模型用记忆化搜索写是要超时的...

    本题的模型可以参考POJ-2955 Brackets题解这里有~

    设dp[i][j]表示区间[i, j]能获得的最大分数状态转移就可以写成

    dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j], dp[i+1][j-1] + value[i] + value[j]);

    剩下的就很简单了。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    const int maxn = 305;
    
    bool judge[maxn][maxn];
    pair<int, int> p[maxn];
    LL sum[maxn], dp[maxn][maxn];
    
    LL gcd(LL a, LL b) {
    	while (b) {
    		LL tmp = a % b;
    		a = b;
    		b = tmp;
    	}
    	return a;
    }
    
    int main() {
    	int n, t;
    	scanf("%d", &t);
    	while (t--) {
    		scanf("%d", &n);
    		sum[0] = 0;
    		for (int i = 1; i <= n; ++i)
    			scanf("%d", &p[i].first);
    		for (int i = 1; i <= n; ++i) {
    			scanf("%d", &p[i].second);
    			sum[i] = sum[i - 1] + p[i].second;
    		}
    		
    		memset(judge, false, sizeof(judge));
    		for (int i = 1; i <= n; ++i) {
    			for (int j = i + 1; j <= n; ++j)
    				judge[i][j] = (gcd(p[i].first, p[j].first) == 1 ? false : true);
    		}
    
    		for (int i = n; i >= 1; --i) {
    			for (int j = i; j <= n; ++j) {
    				dp[i][j] = 0;
    				for (int k = i; k < j; ++k)
    					dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
    				if ((i + 1 == j || dp[i + 1][j - 1] == sum[j - 1] - sum[i]) && judge[i][j])
    					dp[i][j] = max(dp[i][j], dp[i + 1][j - 1] + p[i].second + p[j].second);
    			}
    		}
    		printf("%lld
    ", dp[1][n]);
    	}
    	return 0;
    }


  • 相关阅读:
    python-json序列化和反序列化
    python-列表元祖字典集合、字符、字符串、函数处理
    Nmon监控服务端性能
    python-使用qq邮箱向163邮箱发送邮件、附件
    测试结论
    性能术语
    测试点-app、web、异常
    提测标准
    深度优先搜索的演示学习法——BlackBlank平台应用教学案例
    【赛后补题】ccpc2107秦皇岛H题
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179353.html
Copyright © 2011-2022 走看看