#include <iostream> #include <cstdio> #include <map> #include <algorithm> using namespace std; const int INF = 0x7fffffff; struct Comb{ int sumConsist , sumType; int Consist[ 5 ] , Type[ 5 ]; int Highest; bool tie; Comb(){ tie = false; sumConsist = sumType = Highest = 0; } friend bool operator == ( Comb a , Comb b ){ if( a.sumType != b.sumType || a.sumConsist != b.sumConsist || a.Highest != b.Highest ) return false; for( int i = 0; i < 4; i ++ ) if( a.Consist[ i ] != b.Consist[ i ] || a.Type[ i ] != b.Type[ i ] ) return false; return true; } friend bool operator < ( Comb a , Comb b ){ if( a.sumType == b.sumType ){ if( a.sumConsist == b.sumConsist ) return a.Highest < b.Highest; return a.sumConsist > b.sumConsist; } return a.sumType < b.sumType; } }; int Stamps[ 100 ], CustomerRequests[ 100 ]; int sumStamp, sumCustomer; map< int , int > Pus; map< int , int >::iterator It; bool read(){ sumCustomer = sumStamp = 0; int tmp; while( true ){ if( scanf( "%d" , &tmp ) != EOF ){ It = Pus.find( tmp ); if( It == Pus.end() ){ Pus[ tmp ] = 1; Stamps[ sumStamp ++ ] = tmp; } else { if( It->second < 4 ) {Pus[ tmp ] ++;Stamps[ sumStamp ++ ] = tmp; } } if( tmp == 0 ) break; }else return false; } Pus.clear(); while( scanf("%d" , &CustomerRequests[ sumCustomer ++ ]) , CustomerRequests[ sumCustomer - 1 ] != 0 ); return true; } map< int , Comb > Ans; map< int , Comb >::iterator Pos; void InitAns(){ int cnt; Comb Tmp; for( cnt = 0; cnt < sumCustomer; cnt ++ ) Ans[ CustomerRequests[ cnt ] ] = Tmp; } bool IsSameVal( Comb a, Comb b ) { return a.sumType == b.sumType && a.sumConsist == b.sumConsist && a.Highest == b.Highest; } void dfs( int Sum , int cnt, int * Member, int * Type ){ if( cnt == 4 ){ Pos = Ans.find( Sum ); if( Pos == Ans.end() ) return ; Comb Tmp; int END = sumStamp-1; for( int i = 0; i < 4; i ++ ) { Tmp.Consist[ i ] = Member[ i ]; Tmp.Type[ i ] = Type[ i ]; } sort( Tmp.Consist, Tmp.Consist+4 ); sort( Tmp.Type, Tmp.Type+4); Tmp.sumConsist = Tmp.sumType = 4; for( int i= 3; i >=0; i -- ) { if( Tmp.Consist[ i ] == INF ) Tmp.sumConsist --; else Tmp.Highest = max( Tmp.Highest , Tmp.Consist[ i ] ); if( i != 0 ) if( Tmp.Type[ i ] == END || Tmp.Type[ i ] == Tmp.Type[ i -1 ] ) Tmp.sumType --; if( i == 0 && Tmp.Type[ i ] == END ) Tmp.sumType --; } if( Tmp.sumConsist == 0 || Tmp.sumType == 0 ) return ; if( Tmp == Pos->second ) return ; if( Pos->second < Tmp ) Pos->second = Tmp; else{ if( IsSameVal( Tmp, Pos->second ) ) Pos->second.tie = true; } return ; } for( int i = 0; i < sumStamp; i ++ ){ Member[ cnt ] = ( i == sumStamp - 1 ? INF : Stamps[ i ] ); Type[ cnt ] = i; dfs( Sum+Stamps[i] , cnt+1 , Member , Type ); } } void Print(){ for( int i = 0; i < sumCustomer-1; i ++ ){ int ID = CustomerRequests[ i ]; Comb& Tmp = Ans[ ID ]; if( Tmp.sumType == 0 ) printf("%d ---- none\n", ID ); else if( Tmp.tie ) printf("%d (%d): tie\n", ID , Tmp.sumType ); else{ printf( "%d (%d):", ID , Tmp.sumType ); for( int i = 0; i < Tmp.sumConsist; i ++ ) printf(" %d", Tmp.Consist[ i ]); printf("\n"); } } } void slove(){ InitAns(); int Member[ 5 ] , Type[ 5 ]; dfs( 0, 0, Member, Type ); Print(); Ans.clear(); } int main() { while( read() ) slove(); return 0; }
一直 TLE, 知道看到 ddiscuss 里 一个同学说的神剪枝, 如果相同价值的邮票超过 4 个, 就不用再加进去了, 说这样的话能从TLE到16MS, 我用了这个加上之前自己的一个剪枝 ,0MS过了 如果 一个组合的值不在顾客需求的几何内,那么就没有必要计算了。
附上代码