poj1252-完全背包(正负背包)

这一题我一开始的想法很朴素(就是很裸的意思),就是一正一负,一共12个,接着用完全背包做,没过,看其他人博客上,都是先用正的来一遍完全背包,再用负的来一遍完全背包,问学长,学长说因为递推的时候要从原来的状态过来,正负是不一样的。还是不很理解,我自己的想法就是你先付钱给别人,之后才能找钱吧。

还有一点要注意就是数组要开到2000,原因是可能给的数是互质的,如95,96,97,93,91,89。具体原因我也不是很清楚。上代码

#include
#include
#include
#include
using namespace std;

const int maxn=15;
const int Maxn=2005;
const int INF=0x3f3f3f3f;
int c[maxn];
int f[Maxn];

int main()
{
    //freopen("int.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--){
        memset(f,INF,sizeof(f));
        for(int i=0;i<6;i++){
            scanf("%d",&c[i]);
        }
        int w=1,MAX=-1,sum=0;
        f[0]=0;
        for(int i=0;i<6;i++){
            for(int v=c[i];v<=2000;v++){
                f[v]=min(f[v],f[v-c[i]]+w);
            }
        }
        for(int i=0;i<6;i++){
            for(int v=2000-c[i];v>=0;v--){
                f[v]=min(f[v],f[v+c[i]]+w);
            }
        }
        for(int v=1;v<=100;v++){
            //printf("%d: %d\n",v,f[v]);
            sum+=f[v];
            MAX=max(MAX,f[v]);
        }
        printf("%.2lf %d\n",(double)sum/100.0,MAX);
    }
    return 0;
}



你可能感兴趣的:(acm-背包-完全背包,经典)