hdu 3480 Division

本文介绍了一种使用斜率优化技巧的动态规划算法解决特定问题的方法。通过具体实例讲解了如何利用斜率优化减少状态转移的时间复杂度,并提供了完整的C语言实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dp+斜率优化~~

http://acm.hdu.edu.cn/showproblem.php?pid=3480

View Code
 1 # include<stdio.h>
 2 # include<string.h>
 3 # include<stdlib.h>
 4 # define N 10005
 5 int a[N],s[N],k;
 6 int dp[2][N];
 7 int cmp(const void *a,const void *b)
 8 {
 9     return *(int *)a -*(int *)b;
10 }
11 int K(int i1,int i2,int j)
12 {
13     int x1,y1,x2,y2,x0,y0;
14     y1=dp[(k-1)%2][i1]+a[i1+1]*a[i1+1];
15     x1=a[i1+1];
16     y2=dp[(k-1)%2][i2]+a[i2+1]*a[i2+1];
17     x2=a[i2+1];
18     y0=dp[(k-1)%2][j]+a[j+1]*a[j+1];
19     x0=a[j+1];
20     return (x2-x1)*(y0-y2)-(x0-x2)*(y2-y1);
21 }
22 int G(int j,int i)
23 {
24     return dp[(k-1)%2][j]+(a[j+1]-a[i])*(a[j+1]-a[i]);
25 }
26 int main()
27 {
28     int i,j,n,m;
29     int t,ncase;
30     int f,end,mm;
31     scanf("%d",&ncase);
32     for(t=1;t<=ncase;t++)
33     {
34         scanf("%d%d",&n,&m);
35         for(i=1;i<=n;i++)
36             scanf("%d",&a[i]);
37         printf("Case %d: ",t);
38         if(n<=m) {printf("0\n");continue;}
39         memset(dp,0,sizeof(dp));
40         qsort(a+1,n,sizeof(a[1]),cmp);
41         mm=1;
42         for(i=2;i<=n;i++)
43             if(a[i]!=a[i-1]) a[++mm]=a[i];
44         n=mm;
45         for(i=1;i<=n;i++)
46             dp[1][i]=(a[i]-a[1])*(a[i]-a[1]);
47         for(k=2;k<=m;k++)
48         {
49             f=1;
50             end=0;
51             for(i=k;i<=n;i++)
52             {
53                 j=i-1;
54                 while(end-1>=f && K(s[end-1],s[end],j)<=0) end--;
55                 s[++end]=j;
56                 while(f<end && G(s[f],i)>=G(s[f+1],i)) f++;
57                 dp[k%2][i]=G(s[f],i);
58             }
59         }
60         printf("%d\n",dp[m%2][n]);
61     }
62     return 0;
63 }

 

 

转载于:https://www.cnblogs.com/183zyz/archive/2012/10/24/2737587.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值