原題連結
題解
本質:貪心+dp
首先當我們面對一個矩形時,肯定是不停的列舉其最小邊使得score上漲。
為什麼面對多個矩形不行呢?我們可以注意觀察到最後一組樣例的答案是 35 而非36。
那麼此時我們知曉了每個矩形 得到score 分的運算元 設為cost [ n ][ score ]。
接下來問題就簡化為了在n個矩形中選出最優的 k 分。
很明顯我們考慮dp。
dp [ i ] [ score ] 的含義為從 i ... n 的矩形中得到 score 分所需的運算元。
Ps:dp表可以從二維最佳化到一維。
code
#include<bits/stdc++.h> using namespace std; const int N=1005; int cost[N][205]; int dp[105]; struct node{ int a,b; }; node rect[N]; int n,k; void Init(){ for (int i=1;i<=n;i++){ int a=rect[i].a,b=rect[i].b; cost[i][a+b]=a*b,cost[i][a+b-1]=a*b; int score=0,cos=0; while (a>1 || b>1){ if (a>b) swap(a,b); cos+=a; score++; b-=1; cost[i][score]=cos; // cout<<a<<" "<<b<<endl; } } } void solve(){ cin>>n>>k; for (int i=1;i<=n;i++){ cin>>rect[i].a>>rect[i].b; } Init(); for (int i=0;i<=k;i++) dp[i]=100000; int a=rect[n].a,b=rect[n].b; for (int z=min(k,a+b);z>=0;z--) dp[z]=cost[n][z]; for (int i=n-1;i>=1;i--){ a=rect[i].a,b=rect[i].b; // cout<<i<<" "<<a<<" "<<b<<endl; for (int j=k;j>=0;j--){ for (int z=a+b;z>=0;z--){ dp[j]=min(dp[j],dp[max(0,j-z)]+cost[i][z]); } } } cout<<(dp[k]==100000 ? -1 : dp[k])<<endl; } int main(){ int t; cin>>t; while (t--){ solve(); } return 0; }