HDU4905--The Little Devil II(四邊形不等式優化)

Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

Y*wan defeat the princess's knight party, and finally he meet the devil. But, after that, y*wan feel in love with the devil and become a lolicon. As the king is already died, y*wan become the new king.

Some days passed, the devil feel bored about this boring country and leaves, but the lolicon remains in the country.

The finally hero, you comes as promised, and you figure out a hard problem to defeat y*wan:

There is n integers a_1,a_2,...,a_n on a line, each time we can take two adjacent integers a and b, and replace them by their gcd(a,b), and add gcd(a,b) to the total score. The score is initially the sum of all a_i.After n-1 steps there is only one number left and you stop. What is your maximum score in the end?

After defeat y*wan, you kill WJMZBMR, and save the country.
 

Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains an integer n.
The next line contains n integers a_1,a_2,...,a_n separated by a single space.

T<=20, n<=3000.
a_i >=0
a_i is in the range of int(C++).
 

Output
For each test case, output the result in one line.
 

Sample Input
1 4 1 2 2 4
 

Sample Output
再見後來發現此題不滿足四邊形不等式、、、所以這種做法是錯的=_=。不過這不重要。大笑
14
給個傳送門:http://blog.csdn.net/lmyclever/article/details/6677683
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 3080
int K[maxn][maxn];
int dp[maxn][maxn];
int a[maxn],g[maxn][maxn];
#define LL long long int 
int gcd(int a,int b)
{
	if(!b)	return a;
	return gcd(b,a%b);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;	scanf("%d",&n);
		for(int i = 1;i <= n;i++)	
			scanf("%d",&a[i]);
		for(int i = 1;i <= n;i++)
		{
			g[i][i] = a[i];
			for(int j = i+1;j <= n;j++)
				g[i][j] = gcd(g[i][j-1],a[j]);
		}
		memset(dp,0,sizeof(dp));
		for(int i = 1;i <= n;i++)	
		{
			K[i][i] = i;
		}
		for(int i = n;i >= 1;i--)
		{
			for(int j = i+1;j <= n;j++)
			{
				int a = K[i][j-1],b = K[i+1][j];
				if(a<i)	a = i;	if(b>n)	b = n;
				for(int k = a;k <= b;k++)
				{
					if(k+1 <= j && dp[i][j] < dp[i][k]+dp[k+1][j]+g[i][j])
					{
						dp[i][j] = dp[i][k] + dp[k+1][j] + g[i][j];
						K[i][j] = k;
					}
				}
			}
		}
		LL ans = 0;
		for(int i = 1;i <= n;i++)
			ans += a[i];
		ans += dp[1][n];
		cout << ans << endl;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章