bzoj1597[Usaco2008 Mar]土地购买
生活随笔
收集整理的這篇文章主要介紹了
bzoj1597[Usaco2008 Mar]土地购买
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
bzoj1597[Usaco2008 Mar]土地購買
題意:
n塊土地,現在要求把土地分成幾份,每份費用為該份中土地長最大值和寬最大值成績,要求最小費用。n≤5000
題解:
當一塊土地長寬都比另一塊土地小時,這塊土地可以當作另一塊土地的附屬品,對答案不影響。因此先按長第一關鍵字,寬第二關鍵字排序,然后用單調隊列就可以把長寬都被覆蓋的土地除去。之后剩在單調隊列里的土地長是升序排列,寬是降序排列,故用斜率優化dp:f[i]=max(f[j]+長[i]*寬[j+1]),j比k好當且僅當(f[j]-f[k])/(寬[k+1]-寬[j+1])<長[i]。
代碼:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define maxn 50100 6 #define ll long long 7 using namespace std; 8 9 struct str{ll x,y;}; str strs1[maxn],strs2[maxn]; 10 bool cmp(str a,str b){return a.x!=b.x?a.x<b.x:a.y<b.y;} 11 inline int read(){ 12 char ch=getchar(); int f=1,x=0; 13 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 14 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 15 return f*x; 16 } 17 int n,l,r,m,q[maxn]; ll f[maxn]; 18 double calc(int j,int k){ 19 return (double)(f[j]-f[k])/(double)(strs2[k+1].y-strs2[j+1].y); 20 } 21 int main(){ 22 n=read(); inc(i,1,n)strs1[i].x=(ll)read(),strs1[i].y=(ll)read(); sort(strs1+1,strs1+n+1,cmp); m=0; 23 inc(i,1,n){while(m&&strs2[m].y<=strs1[i].y)m--; strs2[++m]=strs1[i];} l=1; r=1; q[l]=0; 24 inc(i,1,m){ 25 while(l<r&&calc(q[l],q[l+1])<strs2[i].x)l++; f[i]=f[q[l]]+strs2[i].x*strs2[q[l]+1].y; 26 while(l<r&&calc(q[r-1],q[r])>calc(q[r],i))r--; q[++r]=i; 27 } 28 printf("%lld",f[m]); return 0; 29 }?
20160612
轉載于:https://www.cnblogs.com/YuanZiming/p/5779802.html
總結
以上是生活随笔為你收集整理的bzoj1597[Usaco2008 Mar]土地购买的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Servlet简介
- 下一篇: WCF 之 消息契约(MessageCo