刷题dp地精的贸易

Posted xwww666666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题dp地精的贸易相关的知识,希望对你有一定的参考价值。

完全背包

难点:输出方案

wa点:m的范围在一次dp后,出现变化,导致re

 

#include<cstdio>
#include<cstdlib>
using namespace std;
int m,n;
const int N=103,M=1000003;
int a[N],b[N];

int f[2][M];//完全背包(压成一维) 
int pre[2][M];

int ans[N];
int main()
{
    //input
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
    //dp_0    
    for(int i=1;i<=n;i++)
    {
        int val=b[i]-a[i];//卖出价-买入价 
        if(val<=0) continue;
        for(int j=a[i];j<=m;j++)
            if(f[0][j] < f[0][j-a[i]]+val )
            {
                f[0][j]=f[0][j-a[i]]+val;
                pre[0][j]=i;
            }
    }
    int mm=m+f[0][m];
    //dp_1
    for(int i=1;i<=n;i++)
    {
        int val=a[i]-b[i];//卖出价-买入价 
        if(val<=0) continue;
        for(int j=b[i];j<=mm;j++)
            if(f[1][j] < f[1][j-b[i]]+val )
            {
                f[1][j]=f[1][j-b[i]]+val;
                pre[1][j]=i;
            }
    } 
    //find_way => get_excel
    int pos=m;
    while(pre[0][pos])
    {
        ans[pre[0][pos]]++;
        pos-=a[pre[0][pos]];
    }
    pos=mm;
    while(pre[1][pos])
    {
        ans[pre[1][pos]]++;
        pos-=b[pre[1][pos]];
    }
    //output
    printf("%d
",f[0][m]+f[1][mm]);
    for(int i=1;i<=n;i++)
    {
        printf("Buy %d",ans[i]);
        if(ans[i] )
            if(a[i]>b[i]) printf(" from Horde");
            else printf(" from Alliance");
        putchar(
);
    }
    
    return 0;
}

以上是关于刷题dp地精的贸易的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1925 [Sdoi2010]地精部落 dp

按算法刷题路线

地精部落:dp

BZOJ 1925 地精部落(DP)

A - 地精部落 (DP)

BZOJ1925[Sdoi2010]地精部落 组合数+DP