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


  • 相关阅读:
    2018.11.26
    JS数组
    JS2018.12.26
    手机游戏客户端架构设计
    IAP应用内购买
    cocos2dx如何优化内存的应用
    Homebrew
    OS X 文档
    Apple推送通知服务教程
    ajax分页
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179353.html
Copyright © 2011-2022 走看看