原题链接:Problem - F - Codeforces
题意:多测,每组测试数据给出n和k,n代表有n个长方形,k代表需要的到k分,每个长方形都有宽和高,每次可以填涂一个格子,如果填满一列或者一行就可以获得一分,问达到k分最少需要填涂多少格子。
赛时思路:背包dp+随机化,按照背包dp的思路来想,就是选择了某个长方形,如果填满这个长方形分数也不能到达k,那么就直接填满,如果大于等于k那么就用最小代价来填满这个长方形。可以发现这个思路并不可以通过这题,最后一个样例就过不去,发现顺序会影响dp的结果,因为这题的数据量小,并且最小的填涂格子可能不止一种方法,那么就可以想到使用随机化。
补题思路:dp,先求出dp[i][j],i代表第i个长方形,j代表这个长方形得到j分,dp[i][j]代表最小的涂色数,然后就可以理解成对于第i个长方形选择j分就要填涂dp[i][j]个格子,然后就是对于每个长方形都选择一个dp[i][j]来进行dp就可以了。
//冷静,冷静,冷静
//调不出来就重构
#pragma GCC optimize(2)
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=1000000007;
struct node
{ll x,y;
}p[N];
ll f[1010][110];
ll dfs1(ll xz1,ll xz2,ll k)
{if(k<=0)return 0;if(xz1>xz2){swap(xz1,xz2);}if(xz1==xz2&&xz1==1){return 1;}ll d=0,ans=0;for(int i=1;i<=xz2;i++){if(xz2-i+1<xz1){ans+=dfs1(xz1,xz2-i+1,k);return ans;}if(k==0)break;ans+=xz1;k--;}return ans;
}
ll n;
ll dfs(ll x,ll k)
{if(k==0)return 0;if(x>n){if(k)return 1e9;return 0;}if(f[x][k]!=-1)return f[x][k];ll sum=1e9;sum=min(sum,dfs(x+1,k));if(k>=p[x].x+p[x].y){sum=min(sum,dfs(x+1,k-p[x].x-p[x].y)+p[x].x*p[x].y);}else{sum=min(sum,dfs1(p[x].x,p[x].y,k));}f[x][k]=sum;return f[x][k];
}
void Jiuyuan()
{ll k;cin>>n>>k;for(int i=1;i<=n;i++){cin>>p[i].x>>p[i].y;}ll v=100;ll vb=1e18;while(v--){memset(f,-1,sizeof(f));random_shuffle(p+1,p+1+n);ll v1=dfs(1,k);vb=min(v1,vb);}if(vb==1e9){cout<<-1<<endl;}else cout<<vb<<endl;
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);ll T=1;cin>>T;srand(time(0));while(T--){Jiuyuan();}return 0;
}
//冷静,冷静,冷静
//调不出来就重构
//#pragma GCC optimize(2)
//#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=1000000007;
struct node
{ll x,y;
}p[N];
ll c[1010][310],f[1010][310],n;
ll dfs(ll x,ll zhi)
{if(x>n&&zhi)return 1e9;if(zhi<0)return 1e9;if(zhi==0)return 0;if(f[x][zhi]!=-1)return f[x][zhi];ll min1=1e9;for(int i=0;;i++){if(c[x][i]==1e9)break;min1=min(min1,dfs(x+1,zhi-i)+c[x][i]);}f[x][zhi]=min1;return min1;
}
void Jiuyuan()
{ll k;cin>>n>>k;for(int i=1;i<=n;i++){cin>>p[i].x>>p[i].y;for(int j=0;j<=300;j++){c[i][j]=1e9;}}memset(f,-1,sizeof(f));for(int i=1;i<=n;i++){for(int j=0;j<=p[i].x;j++){for(int jk=0;jk<=p[i].y;jk++){ll v=j+jk;c[i][v]=min(c[i][v],jk*p[i].x+j*p[i].y-j*jk);}}}ll v=dfs(1,k);if(v==1e9){cout<<-1<<endl;}else cout<<v<<endl;
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);ll T=1;cin>>T;while(T--){Jiuyuan();}return 0;
}