小馬哥的超級鹽水
阿新 • • 發佈:2018-05-17
HR 分享 b+ nbsp com string close clas 多少
來呀
題意:給n杯鹽水,每一杯水有a單位鹽,b單位水。給你一個x和y,問有多少種方法能配成x比y的鹽水。
因為n只有35,沒法枚舉全部情況,如果n只有一般大,那麽我們可以枚舉所有情況。
我們可以把n分為兩部分,枚舉一部分的所有情況,然後找是否能和另一部分構成解。
對於(a1,b1)和(a2,b2)這兩個集合。
易得(a1+a2)/(b1+b2)=x/y。
化簡得到(y*a1-x*b1)=(x*b2-y*a2)。所以枚舉前面的然後找後面的就行了。
AC代碼:
#include <iostream> #include <string.h> #include <iostream> #includeView Code<algorithm> using namespace std; typedef long long ll; struct node{ ll ai,bi; }a[105]; ll b[1<<19]; int main() { int t;cin>>t; while(t--) { ll n; ll x,y;cin>>n>>x>>y; for(int i=0;i<n;i++) { cin>>a[i].ai>>a[i].bi; }int p=0; ll n1=n/2; ll n2=n-n1; ll m1=(1<<n1); ll m2=(1<<n2); for(int i=0;i<(m2);i++) { ll sum=0; for(int j=0;j<n2;j++) { if((i>>j)&1) { sum+=a[j+n1].bi*x-a[j+n1].ai*y; } } b[p++]=sum; //cout<<ans-1<<endl; } sort(b,b+p); ll ans=0; for(int i=0;i<m1;i++) { ll sum=0; for(int j=0;j<n1;j++) { if((i>>j)&1) { sum+=a[j].ai*y-a[j].bi*x; } } ans+=upper_bound(b,b+p,sum)-lower_bound(b,b+p,sum); } cout<<ans-1<<endl; } return 0; }
小馬哥的超級鹽水