[51nod1614]刷题计划
大赛将至,摆在你面前的是n道题目,第 i(1 ≤ i ≤ n) 道题目能提升 ai 点智力值,代码量为 bi KB,无聊值为 ci ,求至少提升m点智力值的情况下,所做题目代码量之和*无聊值之和最小为多少。
Input
第一行两个整数n,m(0<n<=400)
接下来n行每行三个整数,ai,bi,ci(0<bi,ci<=1000,0<ai<=800)。
0<m<=Σai<=800
Output
一个数,至少提升m点智力值的情况下,所做题目代码量之和*无聊值之和的最小值。
思路和求最小乘积生成树一样。。。不同的就是具体计算的时候是01背包而不是求mst。。。
大概就是将一个方案的b值之和看成X坐标,c值之和看成Y坐标。那么答案的方案肯定就在所有点组成的凸包的左下部分上。
直接丢题解网址了...http://www.51nod.com/onlineJudge/problemSolution.html#!problemId=1614
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cmath> 7 #include<cstdlib> 8 #define ll long long 9 #define ull unsigned long long 10 #define ui unsigned int 11 #define d double 12 #define ld long double 13 const int maxn=808; 14 15 struct zs{int x,y;ll v;}f[maxn],a[maxn]; 16 ll ANS,inf=1ll<<60;int SMA; 17 int A[maxn]; 18 int i,j,k,n,m; 19 20 int ra,fh;char rx; 21 inline int read(){ 22 rx=getchar(),ra=0,fh=1; 23 while(rx<'0'&&rx!='-')rx=getchar(); 24 if(rx=='-')fh=-1,rx=getchar(); 25 while(rx>='0')ra=ra*10+rx-48,rx=getchar();return ra*fh; 26 } 27 28 //bool operator <(zs a,zs b){return a.v<b.v;} 29 zs operator +(zs a,zs b){return (zs){a.x+b.x,a.y+b.y,a.v+b.v};} 30 zs operator -(zs a,zs b){return (zs){a.x-b.x,a.y-b.y,a.v-b.v};} 31 inline int cross(zs a,zs b){return a.x*b.y-a.y*b.x;} 32 33 inline void upd(zs &a,zs &b,zs &c){if(b.v+c.v<a.v)a=b+c;} 34 inline zs get(){ 35 register int i,j,k;zs ans=(zs){0,0,inf}; 36 for(i=1;i<=SMA;i++)f[i].v=inf; 37 for(i=1;i<=n;i++) 38 for(j=SMA,k=j-A[i];j>=A[i];j--,k--)upd(f[j],f[k],a[i]); 39 for(j=m;j<=SMA;j++){ 40 if(f[j].v<ans.v)ans=f[j]; 41 if(1ll*f[j].x*f[j].y<ANS)ANS=1ll*f[j].x*f[j].y; 42 } 43 return ans; 44 } 45 inline void run(zs A,zs B){ 46 for(register int i=1;i<=n;i++)a[i].v=a[i].x*(A.y-B.y)+a[i].y*(B.x-A.x); 47 zs C=get(); 48 if(cross(B-A,C-A)>=0)return; 49 run(A,C),run(C,B); 50 } 51 52 int main(){ 53 n=read(),m=read(); 54 for(i=1;i<=n;i++)A[i]=read(),a[i].x=read(),a[i].y=read(),SMA+=A[i]; 55 56 ANS=inf; 57 for(i=1;i<=n;i++)a[i].v=a[i].x;zs A=get(); 58 for(i=1;i<=n;i++)a[i].v=a[i].y;zs B=get();//printf("sty:%d (%d,%d) stx:%d (%d,%d)\n",A.v,A.x,A.y,B.v,B.x,B.y); 59 //printf("ANS:%lld\n",ANS); 60 run(A,B); 61 printf("%lld\n",ANS); 62 }