题目链接:https://vijos.org/p/1428
这道题其实是非常简单的,就是一个背包的变形。f[i][j]为小的叫i下,大的叫j下的最小价格。那么转移方程非常好写,具体看代码。
#include<bits/stdc++.h>
#define ll long long
#define st string
#define mem(x) memset(x,0,sizeof(x))
using namespace std;
const int INF=1e9;
ll sm[1005];
ll bi[1005];
ll c[1005];
ll f[55][55];
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
memset(f,-1,sizeof(f));
ll n,s,b;
scanf("%lld%lld%lld",&n,&s,&b);
for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&sm[i],&bi[i],&c[i]);
f[0][0]=0;
for(int i=1;i<=n;i++) {
for(int j=s;j>=0;j--) {
for(int k=b;k>=0;k--) {
if(f[j][k]==-1) continue;
ll x=min(s,j+sm[i]);
ll y=min(b,k+bi[i]);
if(f[x][y]!=-1) f[x][y]=min(f[x][y],f[j][k]+c[i]);
else f[x][y]=f[j][k]+c[i];
}
}
}
printf("%lld\n",f[s][b]*2);
return 0;
}
在做这道题的时候,我还是犯了很多错误。
尤其是要注意数组名不能和变量名相同了,这个错有时很难想到。
这道题最关键的问题还是我最初的f数组想的太复杂,用滚动数组直接缩到55*55的状态就好了。这个地方开始我确实被惯性思维给卡住了,最近这种情况出现的次数也比较多,确实应该改一改。我开始想的是前i种饼干j次小的叫声k次大的叫声最小花费。这直接爆内存。其实i这一维可以直接省掉。我确实被惯性思维给卡的死死的。这种智障情况不能再犯了。