穿越火线低端局 F 题司马氏 DP 过不了样例?
思路绝对没问题,但司马氏 DP 总是司马的,也许它沉浸在家族特有的司马悲痛中,求好心人送一片 ygg 让它的马复活
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define rll register ll
#define cll const ll
#define N 1005
using namespace std;
inline ll read()
{
rll x=0;bool f=1;register char c=getchar();
while(c<48||c>57){if(c=='-') f=0;c=getchar();}
while(c>=48&&c<=57){x=x*10+(c^48);c=getchar();}
return f?x:-x;
}
inline void write(ll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+48);
}
ll T,n,k,ans,a[N],b[N],f[N];
map<pair<ll,ll>,ll> g;
inline ll calc(ll x,ll w)
{
rll ta=a[x],tb=b[x],ret=0;
if(w>ta+tb) return 1e18;
if(w==ta+tb) return ta*tb;
while(w--)
{
if(ta<tb)
{
ret+=ta;
tb--;
}
else
{
ret+=tb;
ta--;
}
}
return ret;
}
int main()
{
T=read();
while(T--)
{
n=read(),k=read();
for(rll i=1;i<=n;i++)
a[i]=read(),b[i]=read();
for(rll i=0;i<=k+200;i++)
f[i]=1e18;
f[0]=0;
for(rll i=1;i<=n;i++)
{
for(rll j=k+200;j>=0;j--)
{
if(j>=a[i]+b[i])
f[j]=min(f[j],f[j-(a[i]+b[i])]+a[i]*b[i]);
for(rll l=k+200;l>=j;l--)
f[j]=min(f[j],f[j-l]+calc(i,l));
}
}
if(n==3&&k==11)
{
for(rll i=0;i<=k+200;i++)
cout << "f[" << i << "]=" << f[i] << '\n';
}
ans=1e18;
for(rll i=k;i<=k+200;i++)
ans=min(ans,f[i]);
if(ans==1e18) puts("-1");
else write(ans),putchar('\n');
}
return 0;
}