F. Color Rows and Columns

黑屿白發表於2024-08-16

原題連結

題解

本質:貪心+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;
}

相關文章