$P1282 多米諾骨牌$
阿新 • • 發佈:2019-04-05
splay pro mem == print its 得出 def org
problem
此題是一道01背包。
關於01 背包 我不想講了 - > \(MY \ BLOG\)
\[這道題是一道基礎的01背包問題\]
\[設f[i][j]=k表示前i張牌構成分值j的最小次數k\]
\[設 dis = a[i]-b[i]\]
//不反轉
\[f[i][j+dis+N]=min(f[i][j+dis+N],f[i-1][j+N]);\]
//反轉
\[f[i][j+dis+N]=min(f[i][j+dis+N],f[i-1][j+N]+1);\]
所以得出
\[f[i][j+N] = min(f[i-1][j-dis+N] , f[i-1][j+dis+N] + 1) ;\]
#include <bits/stdc++.h> #define rep(i,j,n) for(register int i=j;i<=n;i++) #define Rep(i,j,n) for(register int i=j;i>=n;i--) #define low(x) x&(-x) using namespace std ; typedef long long LL ; const int inf = INT_MAX >> 1 ; inline LL In() { LL res(0) , f(1) ; register char c ; #define gc c = getchar() while(isspace(gc)) ; c == '-' ? f = - 1 , gc : 0 ; while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(gc)) ; return res * f ; #undef gc } int n ; const int Size = 1000 + 5 ; const int N = 5000 ; int a[Size] , b[Size] ; int f[Size][Size * 11] ; int ans ; inline void Ot() { n = In() ; rep(i,1,n) a[i] = In() , b[i] = In() ; memset(f,0x7f,sizeof(f)) ; f[0][N] = 0 ; rep(i,1,n) rep(j,-N,N) { int dis = a[i] - b[i] ; f[i][j+N] = min(f[i-1][j-dis+N] , f[i-1][j+dis+N] + 1) ; } rep(i,0,N) { int ans = min(f[n][N+i] , f[n][N-i]) ; if(ans <= 1000) { printf("%d\n",ans) ; return ; } } } signed main() { // freopen("testdata.txt","w",stdout) ; return Ot() , 0 ; }
$P1282 多米諾骨牌$