题目:
分析:这里给的搜素题,总觉得不是很好。
终于遇到一道还不错的。
本以为是基础。
0优化代码:
#include <bits/stdc++.h>
using namespace std;
long long A[ 50 ] ;
int m;
long long n;
long long ans= 0 ;
void f ( long long rest, int num)
{
if ( num== n) { ans++ ; return ; }
if ( rest< A[ num] )
{
ans++ ;
return ;
}
f ( rest, num+ 1 ) ;
f ( rest- A[ num] , num+ 1 ) ;
}
int main ( )
{
cin>> m>> n;
for ( int i= 0 ; i< m; i++ ) cin>> A[ i] ;
sort ( A, A+ m) ;
f ( n, 0 ) ;
cout<< ans;
}
相同的应该是可以优化的:
引入一个c—组合数,相同的可以极大的节省
代码:
#include <bits/stdc++.h>
using namespace std;
int m;
long long n;
long long ans= 0 ;
long long cc[ 41 ] [ 41 ] ;
map< long long , int > mm;
vector< long long > v;
void fc ( )
{
for ( int i= 0 ; i< 41 ; i++ ) cc[ i] [ 0 ] = 1 ;
for ( int i= 1 ; i< 41 ; i++ )
for ( int j= 1 ; j<= i; j++ ) cc[ i] [ j] = cc[ i] [ j- 1 ] * ( i- j+ 1 ) / j;
}
void f ( long long rest, int num, long long b)
{
if ( num== v. size ( ) ) { ans+ = b; return ; }
if ( rest< v[ num] )
{
ans+ = b;
return ;
}
f ( rest, num+ 1 , b) ;
for ( int i= 1 ; i<= mm[ v[ num] ] ; i++ )
{
if ( i* v[ num] <= rest)
{
f ( rest- i* v[ num] , num+ 1 , b* cc[ mm[ v[ num] ] ] [ i] ) ;
}
else break ;
}
}
int main ( )
{
fc ( ) ;
cin>> m>> n;
for ( int i= 0 ; i< m; i++ )
{
long long c;
cin>> c;
if ( mm[ c] != 0 ) { mm[ c] ++ ; continue ; }
mm[ c] ++ ;
v. push_back ( c) ;
}
sort ( v. begin ( ) , v. end ( ) ) ;
f ( n, 0 , 1 ) ;
cout<< ans;
}
竟然只通过了40。
看来我小看了省选/NOI-的难度。
看题解:
折半搜索:
我也没理解为什么能降低的比我的还多。
代码:很容易理解,就是分成两部分,用一个数组记录所有可能的搜索结果。然后用stl的搜索函数进行合并。
代码:
#include <bits/stdc++.h>
using namespace std;
long long A[ 50 ] ;
int m;
long long n;
long long ans= 0 ;
long long suma[ 1 << 21 ] , sumb[ 1 << 21 ] ;
void f1 ( long long sum, int l, int r, long long & cnt)
{
if ( sum> n) return ;
if ( l> r)
{
suma[ cnt] = sum;
cnt++ ;
return ;
}
f1 ( sum+ A[ l] , l+ 1 , r, cnt) ;
f1 ( sum, l+ 1 , r, cnt) ;
}
void f2 ( long long sum, int l, int r, long long & cnt)
{
if ( sum> n) return ;
if ( l> r)
{
sumb[ cnt] = sum;
cnt++ ;
return ;
}
f2 ( sum+ A[ l] , l+ 1 , r, cnt) ;
f2 ( sum, l+ 1 , r, cnt) ;
}
int main ( )
{
cin>> m>> n;
for ( int i= 0 ; i< m; i++ ) cin>> A[ i] ;
long long cnta= 0 ;
long long cntb= 0 ;
f1 ( 0 , 0 , m>> 1 , cnta) ;
f2 ( 0 , ( m>> 1 ) + 1 , m- 1 , cntb) ;
sort ( suma, suma+ cnta) ;
for ( int i= 0 ; i< cntb; i++ )
{
ans+ = upper_bound ( suma, suma+ cnta, n- sumb[ i] ) - suma;
}
cout<< ans;
}