P1417 烹调方案//基础背包 卡longlong

我又一次失败了

这道题看起来是01背包,但是有需要注意的地方

对于这个我用一种易懂的方式说一下

平常做01背包的题时,由于i的价值永远是不变的,所以i讨论的顺序对结果不影响

但是这道题中,如果你先讨论了1号点,再讨论第二点,第二点的价值会减小,反之一号点会减小,这两个哪个更优是不确定的,所以如果你先讨论1号点就会错

由此,需要按优先度对所有点进行排序

//luogu 1417 wjz 1611161121
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long 
using namespace std;
const LL MAXN = 100000 + 10;
LL T, n;
LL f[MAXN];
struct node    //c[x]*b[y]<c[y]*b[x]
{
    LL a, b, c;
} m[MAXN];
bool cmp(node x, node y)
{
    return x.c * y.b < y.c * x.b;
}
int main()
{
    cin >> T >> n;    
    for(LL i = 1; i <= n; i++) cin >> m[i].a;
    for(LL i = 1; i <= n; i++) cin >> m[i].b;
    for(LL i = 1; i <= n; i++) cin >> m[i].c;
    sort(m+1, m+1+n, cmp);
    for(LL i = 1; i <= n; i++)
        for(LL j = T; j - m[i].c >= 0; j--)
            f[j] = max(f[j], f[j-m[i].c] + m[i].a - j * m[i].b);
    LL maxx = 0;
    for(LL i = 1; i <= T; i++)
        maxx = max(f[i], maxx);
    cout << maxx;
    return 0;
}

我:

#include<set>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
using namespace std;
int n,t;
int f[55];
struct infor
{
    int ai;
    int bi;
    int ci;
}a[55];
int main()
{
    scanf("%d%d",&t,&n);
    int i,j;
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i].ai);
        scanf("%d",&a[i].bi);
        scanf("%d",&a[i].ci);
    }
    for(i=1;i<=n;i++)
    {
        for(j=t-a[i].ci;j>=1;j--)
        {
           f[j]=max(f[j+a[i].ci]+a[i].ai-j*a[i].bi,f[j]);    
        }
    }
    cout<<f[1]<<endl;
    
    return 0;
}
原文地址:https://www.cnblogs.com/voldemorte/p/7617873.html