FZOJ1808 多米诺骨牌

fzoj1808

状态

dp[i][j]表示前i个骨牌差值为j的最小翻转次数
初始化:dp[0][sum]为0,其余为INF
状态转移方程:dp[i][j]=min(dp[i][j],dp[i-1][j+del[i]]);//不翻
dp[i][j]=min(dp[i][j],dp[i-1][j-del[i]]+1);//翻

#include
#include
#include
#include
using namespace std;
int del[1001],dp[1001][10001];
int main()
{
    memset(dp,0x3f,sizeof(dp));
    freopen("in.txt","r",stdin);
    int n,sum=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int up,down;
        scanf("%d%d",&up,&down);
        del[i]=up-down;
        sum+=abs(del[i]);
    }
    dp[0][sum]=0;
    for(int i=1;i<=n;i++)for(int j=0;j<=sum*2;j++)
    {
        dp[i][j]=min(dp[i][j],dp[i-1][j+del[i]]);
        dp[i][j]=min(dp[i][j],dp[i-1][j-del[i]]+1);
    }
    for(int i=0;i<=sum;i++)
    if(dp[n][sum+i]0][0]||dp[n][sum-i]0][0])//此时dp[0][0]为INF 
    {
        printf("%d ",min(dp[n][sum+i],dp[n][sum-i]));
        break;
    }
    return 0;
}

你可能感兴趣的:(背包DP,dp,背包问题)