poj1717 Dominoes (背包)

来源:互联网 发布:linux dhcp server 编辑:程序博客网 时间:2024/05/21 22:54
Dominoes

Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 6665Accepted: 2211

Description

A domino is a flat, thumbsized tile, the face of which is divided into two squares, each left blank or bearing from one to six dots. There is a row of dominoes laid out on a table:



The number of dots in the top line is 6+1+1+1=9 and the number of dots in the bottom line is 1+5+3+2=11. The gap between the top line and the bottom line is 2. The gap is the absolute value of difference between two sums.


Each domino can be turned by 180 degrees keeping its face always upwards.


What is the smallest number of turns needed to minimise the gap between the top line and the bottom line?


For the figure above it is sufficient to turn the last domino in the row in order to decrease the gap to 0. In this case the answer is 1.

Write a program that: computes the smallest number of turns needed to minimise the gap between the top line and the bottom line.

Input

The first line of the input contains an integer n, 1 <= n <= 1000. This is the number of dominoes laid out on the table.


Each of the next n lines contains two integers a, b separated by a single space, 0 <= a, b <= 6. The integers a and b written in the line i + 1 of the input file, 1 <= i <= 1000, are the numbers of dots on the i-th domino in the row, respectively, in the top line and in the bottom one.

Output

Output the smallest number of turns needed to minimise the gap between the top line and the bottom line.

Sample Input

4 
6 1
1 5
1 3
1 2

Sample Output

1 

Source

CEOI 1997



这道题就是说麻将可以上下翻动,是使得上下点数和的差最小的时候最少的翻转步数。

第一种方法,我们把每一个的上下差值作为容量,我们每取一个容量,价值就加1,由此可以转化为01背包。

/************************** *Create time: Mon Aug 01 09:04:35 2016 *Author: Mymilkbottles *File name: POJ1717**************************/#include<iostream>using namespace std;#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stdlib.h>#include<vector>#include<queue>#include<deque>#include<map>#include<set>#include<time.h>#define pi(x,y) printf("%d%c",(x),(y));#define pin(x) printf("%d\n",(x));#define si(x) scanf("%d",&(x))#define sii(x,y) scanf("%d%d",&(x),&(y))#define s3(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))#define rep(x,y,z) for(int (x)=(y);(x)<(z);++(x))#define dep(x,y,z) for(int (x)=(y)-1;(x)>=(z);--(x))#define read int TcaseN;scanf("%d",&TcaseN);for(int Tcase=1;Tcase<=TcaseN;++Tcase)#define cls(x,y) memset((x),(y),sizeof((x)));#define pb(x) push_back(x)#define mp(x,y) make_pair((x),(y))#define max3(value_a,value_b,value_c) max(max(value_a,value_b),value_c)#define min3(value_a,value_b,value_c) min(min(value_a,value_b),value_c)#define GT(x) (x)=clock();///In This You Can Define Long Integer Type#define LONGTYPE long longtypedef LONGTYPE LL;typedef unsigned LONGTYPE ULL;const int maxint=((~((unsigned)(0)))>>1);const LL maxll=((~((unsigned LONGTYPE)(0)))>>1);const int inf=0x3f3f3f3f;const double PI=acos(-1.0);const int maxn=1e4+5008;const int mid=7002;const int maxm=1005;int dp[maxn];int a[maxm];inline int mins(int aa,int bb) {    return aa<bb?aa:bb;}int main() {#ifdef tangge    clock_t tSTART,tEND,t3;    GT(tSTART);#endif // tangge    int n,u,v,sum=0,fi=0;    while(~si(n)) {        fi=sum=0;        rep(i,0,n) {            sii(u,v);            fi+=u,sum+=(u+v),a[i]=u-v;        }        if((fi<<1)==sum) {            puts("0");            continue;        }        cls(dp,inf)        dp[mid]=0;        rep(i,0,n) {            if(a[i]>0) {                dep(j,sum+mid+1,a[i]) {                    if(dp[j-a[i]]^inf)dp[j]=mins(dp[j],dp[j-a[i]]+1);                }            } else {                rep(j,0,sum+mid-a[i]+1) {                    if(dp[j-a[i]]^inf) {                        dp[j]=mins(dp[j],dp[j-a[i]]+1);                    }                }            }        }        int t=inf,ans=inf,fl;        rep(i,0,sum+mid+1) {            if(dp[i]==inf) continue;            fl=abs((fi-i+mid)-(sum-(fi-i+mid)));            if(t>fl) {                t=fl;                ans=dp[i];            } else if(t==fl&&ans>dp[i]) {                ans=dp[i];            }        }        printf("%d\n",ans);    }#ifdef tangge    GT(tEND);    printf("%.8lf\n",(tEND-tSTART)/1000.0);#endif // tangge    return 0;}

第二种方法:
我们可以使用分组背包解决,一共n组,每组选一个且必须选一个。
有一个地方,状态转移的时候我们是+k而不是+1,因为我们选的是上下面的,我们不是两种情况都需要翻转。

/************************** *Create time: Mon Aug 01 10:58:29 2016 *Author: Mymilkbottles *File name: POJ1717.1.cpp**************************/#include<iostream>using namespace std;#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stdlib.h>#include<vector>#include<queue>#include<deque>#include<map>#include<set>#include<time.h>#define pi(x,y) printf("%d%c",(x),(y));#define pin(x) printf("%d\n",(x));#define si(x) scanf("%d",&(x))#define sii(x,y) scanf("%d%d",&(x),&(y))#define s3(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))#define rep(x,y,z) for(int (x)=(y);(x)<(z);++(x))#define dep(x,y,z) for(int (x)=(y)-1;(x)>=(z);--(x))#define read int TcaseN;scanf("%d",&TcaseN);for(int Tcase=1;Tcase<=TcaseN;++Tcase)#define cls(x,y) memset((x),(y),sizeof((x)));#define pb(x) push_back(x)#define mp(x,y) make_pair((x),(y))#define max3(value_a,value_b,value_c) max(max(value_a,value_b),value_c)#define min3(value_a,value_b,value_c) min(min(value_a,value_b),value_c)#define GT(x) (x)=clock();///In This You Can Define Long Integer Type#define LONGTYPE long longtypedef LONGTYPE LL;typedef unsigned LONGTYPE ULL;const int maxint=((~((unsigned)(0)))>>1);const LL maxll=((~((unsigned LONGTYPE)(0)))>>1);const int inf=0x3f3f3f3f;const double PI=acos(-1.0);const int maxn=1e3+5;int a[2][maxn];int dp[maxn][maxn*6];int main() {#ifdef tangge    clock_t tSTART,tEND,t3;    GT(tSTART);#endif // tangge    int n,sum,fl;    while(~si(n)) {        sum=0;        rep(i,1,n+1) {            sii(a[0][i],a[1][i]);            sum+=a[0][i],sum+=a[1][i];        }        cls(dp,-1)        dp[0][0]=0;        rep(i,1,n+1) {            dep(j,sum+1,0) {                rep(k,0,2) {                    if(j<a[k][i]) continue;                    if(dp[i-1][j-a[k][i]]^-1) {                        dp[i][j]=(dp[i][j]==-1)?(dp[i-1][j-a[k][i]]+k):min(dp[i-1][j-a[k][i]]+k,dp[i][j]);                    }//if(dp[i][j]^-1)cout<<"i="<<i<<" j="<<j<<" k="<<k<<" dp="<<dp[i][j]<<" dp="<<dp[i-1][j-a[k][i]]<<endl;;                }            }        }        int tv=inf,ans=inf;        rep(i,0,sum+1) {            if(dp[n][i]<0)continue;            fl=abs(i-(sum-i));            if(tv>fl) {                ans=dp[n][i];//min(dp[n][i],n-dp[n][i]);                tv=fl;            } else if(tv==fl)                ans=min(dp[n][i],ans);//min(ans,min(dp[n][i],n-dp[n][i]));        }        pin(ans);    }#ifdef tangge    GT(tEND);    printf("%.8lf\n",(tEND-tSTART)/1000.0);#endif // tangge    return 0;}

这是二维的,我们可以优化成一维的,会快很多。

/************************** *Create time: Mon Aug 01 10:58:29 2016 *Author: Mymilkbottles *File name: POJ1717.1.cpp**************************/#include<iostream>using namespace std;#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stdlib.h>#include<vector>#include<queue>#include<deque>#include<map>#include<set>#include<time.h>#define pi(x,y) printf("%d%c",(x),(y));#define pin(x) printf("%d\n",(x));#define si(x) scanf("%d",&(x))#define sii(x,y) scanf("%d%d",&(x),&(y))#define s3(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))#define rep(x,y,z) for(int (x)=(y);(x)<(z);++(x))#define dep(x,y,z) for(int (x)=(y)-1;(x)>=(z);--(x))#define read int TcaseN;scanf("%d",&TcaseN);for(int Tcase=1;Tcase<=TcaseN;++Tcase)#define cls(x,y) memset((x),(y),sizeof((x)));#define pb(x) push_back(x)#define mp(x,y) make_pair((x),(y))#define max3(value_a,value_b,value_c) max(max(value_a,value_b),value_c)#define min3(value_a,value_b,value_c) min(min(value_a,value_b),value_c)#define GT(x) (x)=clock();///In This You Can Define Long Integer Type#define LONGTYPE long longtypedef LONGTYPE LL;typedef unsigned LONGTYPE ULL;const int maxint=((~((unsigned)(0)))>>1);const LL maxll=((~((unsigned LONGTYPE)(0)))>>1);const int inf=0x3f3f3f3f;const double PI=acos(-1.0);const int maxn=1e3+5;int dp[12005];int main() {#ifdef tangge    clock_t tSTART,tEND,t3;    GT(tSTART);#endif // tangge    int n,sum,fl,u,v;    si(n);    {        sum=0;        cls(dp,-1)        dp[0]=0;        rep(i,1,n+1) {            sii(u,v);            sum+=u+v;            dep(j,sum+1,0) {                if(dp[j]^-1) {                    int t=dp[j];                    dp[j]=-1;                    if(dp[j+u]==-1||dp[j+u]>t) {                        dp[j+u]=t;                    }                    if(dp[j+v]==-1||dp[j+v]>t+1) {                        dp[j+v]=t+1;                    }                }            }        }        sum/=2;        int i, j;        for(i = sum; i >= 0; i--) {            if(dp[i] != -1)                break;        }        for(j = sum; j < 12005; j++) {            if(dp[j] != -1)                break;        }        printf("%d\n", dp[i] > dp[j] ? dp[j] : dp[i]);//        int f1,f2;//        rep(i,sum,maxn){//            if(dp[i]^-1){//                f1=dp[i];break;//            }//        }//        dep(i,sum+1,0){//            if(dp[i]^-1){//                f2=dp[i];break;//            }//        }//        pin(min(f1,f2));//        int tv=inf,ans=inf;//        rep(i,0,sum+1){//            if(dp[i]^-1){//                int t=abs(i-sum+i);//                if(tv>t){//                    ans=dp[i];//                    tv=t;//                }else if(tv==t)ans=min(ans,dp[i]);//            }//        }//        pin(ans);    }#ifdef tangge    GT(tEND);    printf("%.8lf\n",(tEND-tSTART)/1000.0);#endif // tangge    return 0;}
1 0
原创粉丝点击