小H的小屋
阿新 • • 發佈:2020-06-30
題解 [NOI2004]小H的小屋
前記
又鴿了好久,這回可要努力更新了
2019.6.2,痛下殺心,把電腦上所有的遊戲都刪掉了,提前160天奮力備考NOIP。目標:A類省隊!
題解
這道題唯一的難點就在於貪心
從簡單開始,假如一個矩形需要分成兩部分,要求面積最小(參照題意)。那麼均分肯定時最優解
如圖,紫色是大的矩形,橙色是均分的兩個小矩形,藍色是非均分的兩個小矩形。顯而易見的是,橙色面積要比藍色小。由於是貪心嘛其實是懶得嚴格證明,我們發現分成兩個的情況下,均分最優
那麼把情況擴充套件以下,由於貪心思想這回是因為我不會嚴格證明,均分思想可以推廣到分成更多的小矩形的情況中
好了有了均分的思想,還有一個問題:假如\(n \mod m \ne 0\)
也好辦,儘可能湊成對齊的就好了嘛
\ | 北牆 | 南牆 |
---|---|---|
一部分 | \(ln = m-n\mod m\) | \(lr = \lfloor \frac{n}{m} \rfloor\) |
另一部分 | \(rn = n\mod m\) | \(rs = \lfloor \frac{n}{m} \rfloor + 1\) |
醬紫就可以保證滿足均分思想
假設\(area(x,y,k)\)表示在橫座標長度為y的矩形中分x份,斜率為k
double area(int x,int y,double k){ // x kuai in y len return (double)(x-y%x)*(y/x)*k*(y/x)+(y%x)*(y/x+1)*k*(y/x+1); }
當\(n\mod m=0\)時
\(ans=area(n,100,k1)+area(m,100,k2)\)
當\(n\mod m\ne 0\)時
\(ans=min_{i=ln\times lr} ^ {100-rn*rs} area(ln,i,k1)+area(ln\times ls,i,k2)+area(rn,100-i,k1)+area(rn\times rs,100-i,k2)\)
然後據說ans關於i是個單峰函式,不過反正i最大不過迴圈100次,我也不會證明這個函式的單調性,就算了吧。
code:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int m,n,ln,ls,rn,rs; double k1,k2,ans; double area(int,int,double); int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); #endif scanf("%lf%lf%d%d",&k1,&k2,&m,&n); if(n%m==0){ ans+=area(m,100,k1); ans+=area(n,100,k2); printf("%.1lf\n",ans); return 0; } ln=m-n%m; ls=n/m; rn=n%m; rs=(n/m+1); ans=2147483647.0; for(int i=ln*ls;i<=100-rn*rs;++i){ double tmp=0.0; tmp+=area(ln,i,k1); tmp+=area(ln*ls,i,k2); tmp+=area(rn,100-i,k1); tmp+=area(rn*rs,100-i,k2); ans=min(ans,tmp); } printf("%.1lf\n",ans); return 0; } double area(int x,int y,double k){ // x kuai in y len return (double)(x-y%x)*(y/x)*k*(y/x)+(y%x)*(y/x+1)*k*(y/x+1); }
後記
距 NOIp2019 還剩 159 天
你已經在洛谷連續打卡了 266 天,獎勵積分 4
衝鴨!