您的位置:首页 > 其它

HDU 3480 Division (两个状态的斜率优化DP)

2018-01-23 11:51 344 查看

Division

[b]Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others)

Total Submission(s): 5327    Accepted Submission(s): 2103
[/b]

[align=left]Problem Description[/align]
Little D is really interested in the theorem of sets recently. There’s a problem that confused him a long time.  

Let T be a set of integers. Let the MIN be the minimum integer in T and MAX be the maximum, then the cost of set T if defined as (MAX – MIN)^2. Now given an integer set S, we want to find out M subsets S1, S2, …, SM of S, such that



and the total cost of each subset is minimal.
 

[align=left]Input[/align]
The input contains multiple test cases.

In the first line of the input there’s an integer T which is the number of test cases. Then the description of T test cases will be given. 

For any test case, the first line contains two integers N (≤ 10,000) and M (≤ 5,000). N is the number of elements in S (may be duplicated). M is the number of subsets that we want to get. In the next line, there will be N integers giving set S.

 

[align=left]Output[/align]
For each test case, output one line containing exactly one integer, the minimal total cost. Take a look at the sample output for format.

 

[align=left]Sample Input[/align]


23 21 2 44 24 7 10 1

 
[align=left]Sample Output[/align]


Case 1: 1Case 2: 18

题意:

给你n个点,要你分成m个集合,使得分成的这些集合的总价值最小,value+=(子集合里面的最大值-子集合里面的最小值)^2

解析:

其实就是两个状态的DP,第一个状态是集合元素,第二个状态是当前集合数

DP[i][j]为前i个元素分成j组的最小值

状态转移方程是dp[i][k]=min{dp[j][k-1]+(a[i]-a[j+1])^2}  k<m,j<i

DP两个状态->二维数组

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long int lli;

const int MAXM = 5e3 +10;
const int MAXN = 1e4 +10;

#define INF 0x3f3f3f3f

//lli sum[MAXN];
lli xb[MAXN];
lli dp[MAXN][MAXM];
lli q[MAXN],head,tail;
lli n,m;
lli DP(int i,int j,int c)
{
return dp[j][c-1]+(xb[i]-xb[j+1])*(xb[i]-xb[j+1]);
}

lli UP(int i,int j,int c)
{
return dp[i][c-1]+xb[i+1]*xb[i+1]-dp[j][c-1]-xb[j+1]*xb[j+1];
}

lli DOWN(int i,int j)
{
return xb[i+1]-xb[j+1];
}

int main()
{
int t;
scanf("%d",&t);
int ncount=0;
while(t--)
{
scanf("%lld%lld",&n,&m);
ncount++;
for(int i=1;i<=n;i++)
{
scanf("%lld",&xb[i]);
}
sort(xb+1,xb+1+n);
dp[0][0]=0;
for(int i=1;i<=n;i++)
dp[i][1]=DP(i,0,0);
for(int j=2;j<=m;j++)
{
tail=head=0;
q[tail++]=0;
for(int i=1;i<=n;i++)
{
while(head+1<tail&&UP(q[head+1],q[head],j)<=2*xb[i]*DOWN(q[head+1],q[head]))
head++;
dp[i][j]=DP(i,q[head],j);
int p=i;
while(head+1<tail&&UP(p,q[tail-1],j)*DOWN(q[tail-1],q[tail-2])<=UP(q[tail-1],q[tail-2],j)*DOWN(p,q[tail-1]))
tail--;

q[tail++]=p;
}
}
printf("Case %d: %lld\n",ncount,dp
[m]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM HDU DP