多米诺骨牌
题目描述
多米诺骨牌由上下 2 2 2 个方块组成,每个方块中有 1 ∼ 6 1\sim6 1∼6 个点。现有排成行的上方块中点数之和记为 S 1 S_1 S1,下方块中点数之和记为 S 2 S_2 S2,它们的差为 ∣ S 1 − S 2 ∣ \left|S_1-S_2\right| ∣S1−S2∣。如图, S 1 = 6 + 1 + 1 + 1 = 9 S1=6+1+1+1=9 S1=6+1+1+1=9, S 2 = 1 + 5 + 3 + 2 = 11 S2=1+5+3+2=11 S2=1+5+3+2=11, ∣ S 1 − S 2 ∣ = 2 \left|S_1-S_2\right|=2 ∣S1−S2∣=2。每个多米诺骨牌可以旋转 180 ° 180° 180°,使得上下两个方块互换位置。请你计算最少旋转多少次才能使多米诺骨牌上下 2 2 2 行点数之差达到最小。
对于图中的例子,只要将最后一个多米诺骨牌旋转 180 ° 180° 180°,即可使上下 2 2 2 行点数之差为 0 0 0。
输入格式
输入文件的第一行是一个正整数 n ( 1 ≤ n ≤ 1000 ) n(1\leq n\leq 1000) n(1≤n≤1000),表示多米诺骨牌数。接下来的 n n n 行表示 n n n 个多米诺骨牌的点数。每行有两个用空格隔开的正整数,表示多米诺骨牌上下方块中的点数 a a a 和 b b b,且 1 ≤ a , b ≤ 6 1\leq a,b\leq 6 1≤a,b≤6。
输出格式
输出文件仅一行,包含一个整数。表示求得的最小旋转次数。
样例 #1
样例输入 #1
4
6 1
1 5
1 3
1 2
样例输出 #1
1
代码内容
// #include <iostream>
// #include <algorithm>
// #include <cstring>
// #include <stack>//栈
// #include <deque>//队列
// #include <queue>//堆/优先队列
// #include <map>//映射
// #include <unordered_map>//哈希表
// #include <vector>//容器,存数组的数,表数组的长度
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=1e3+10;
const ll N=5000;
ll a[M],b[M];
int f[M][12*M];
int main()
{
ll n;
cin>>n;
for(ll i=1;i<=n;i++)
cin>>a[i]>>b[i];
//初始化
memset(f,0x7F,sizeof f);
f[0][0+N]=0;
for(ll i=1;i<=n;i++)
for(ll j=-5000;j<=5000;j++)
{
ll dis=a[i]-b[i];//点数之差
f[i][j+N]=min(f[i-1][j-dis+N],f[i-1][j+dis+N]+1);
}
for(ll i=0;i<=5000;i++)
{
ll ans=min(f[n][N+i],f[n][N-i]);
if(ans<=1000)
{
cout<<ans<<endl;
break;
}
}
return 0;
}