洛谷 P1282 多米诺骨牌

来源:互联网 发布:windows线程优先级设置 编辑:程序博客网 时间:2024/05/29 08:33

背包DP

题目传送门

记录a[i]为上下骨牌的差值,设其为物品的质量,每个物品的体积为1。那么问题就转化成了一个背包问题。

f[i][j]表示前i个物品,质量为j时能达到的最小体积。
但是很显然质量可能是负的,于是我们给所有质量加上一个大数,然后依然取最小值。
注意数组越界。(就是因为这个我RE了三发。。。)

代码:

#include<cstdio>#include<cstring>#include<algorithm>#define MAXN 1000#define MAXM 10000using namespace std;int n;int a[MAXN+5];int f[MAXN+5][MAXM+5];int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++){        int x,y;        scanf("%d%d",&x,&y);        a[i]=x-y;    }    memset(f,63,sizeof(f));    f[0][0+MAXM]=0;    for (int i=1;i<=n;i++)        for (int j=-MAXM/2;j<=MAXM/2;j++)            f[i][j+MAXM]=min(f[i-1][j-a[i]+MAXM],f[i-1][j+a[i]+MAXM]+1);    int ans=MAXM*MAXN;    for (int i=0;i<=MAXM/2;i++){        ans=min(ans,min(f[n][MAXM+i],f[n][MAXM-i]));        if (ans<=1000) break;//因为要求绝对值最小,因此一旦有解就输出    }    printf("%d\n",ans);    return 0;}
原创粉丝点击