洛谷P1282 多米诺骨牌
洛谷P1282 多米诺骨牌
动态规划
题意: 对多米诺骨牌进行翻转,使其上下值最接近,求最小的翻转次数
dp[ i ][ j ] 表示上面那排前i个数 和为 j 所需要的最小的翻转次数
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iomanip> 8 #include <iostream> 9 using namespace std ; 10 11 const int maxn = 1001,inf = 1e9 ; 12 int n,tot,v,x,ans ; 13 int a[maxn],b[maxn],dp[maxn][6001] ; 14 15 int main() 16 { 17 scanf("%d",&n) ; 18 for(int i=1;i<=n;i++) 19 { 20 scanf("%d%d",&a[ i ],&b[ i ]) ; 21 tot = tot + a[ i ] + b[ i ] ; 22 v = v + max( a[ i ],b[ i ] ) ; 23 } 24 25 for(int i=0;i<=n;i++) 26 for(int j=0;j<=v;j++) dp[i][j] = inf ; 27 dp[ 0 ][ 0 ] = 0 ; 28 for(int i=1;i<=n;i++) 29 { 30 for(int j=0;j<=v;j++) 31 { 32 if(j-a[ i ]>=0) dp[ i ][ j ] = min(dp[ i ][ j ],dp[ i-1 ][ j-a[i] ]) ; 33 if(j-b[ i ]>=0) dp[ i ][ j ] = min(dp[ i ][ j ],dp[ i-1 ][ j-b[i] ]+1) ; 34 } 35 } 36 37 x = tot>>1 ; 38 for(int i=x;i;i--) 39 { 40 ans = min(dp[n][i],dp[n][tot-i]) ; 41 if(ans<inf) 42 { 43 printf("%d\n",ans ) ; 44 return 0 ; 45 } 46 } 47 48 return 0 ; 49 }