电阻
类欧几里得算法。
如果当前所需电阻
- 大于$1$,串联 $1$Ω 电阻
- 小于$1$,并联 $1$Ω 电阻
1 #include<bits/stdc++.h> 2 using namespace std; 3 ll a,b,ans; 4 int main() { 5 cin>>a>>b; 6 while(a>0&&b>0) { 7 if(a>=b) ans+=a/b,a%=b; 8 else ans+=b/a,b%=a; 9 } 10 cout<<ans; 11 }
找零
已经能组合出的面值为$1$~$now$。考虑$now+1$的面值组合,必然为$0$~$now$的一个面值加上一个硬币的面值($a[tmp]$),易得$0<a[tmp]le now+1$。选用$a[tmp]$后,能组合出的面值更新为$1$ ~ $now+a[tmp]$,($now+1$ : $now+1-a[tmp]$的组合加上$a[tmp]$,$now+2$ : $now+2-a[tmp]$的组合加上$a[tmp]$,以此类推至$now+a[tmp]$ : $now$的组合加上$a[tmp]$)。
由此可得,要用尽量少的硬币,每次选用的$a[tmp]$的值越大越好。所以我们每次二分找出面值小于等于$now+1$的硬币中面值最大的作为$a[tmp]$。
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=1e6+5; 5 ll n,x,now,ans,a[N]; 6 7 int main() { 8 x=read(),n=read(); 9 for(int i=1;i<=n;i++) a[i]=read(); 10 sort(a+1,a+n+1); 11 if(a[1]!=1) return puts("-1"),0; 12 while(now<x) { 13 int tmp=upper_bound(a+1,a+n+1,now+1)-a-1; 14 //在面值小于等于now+1的硬币中找面值最大的 15 ans++,now+=a[tmp]; 16 } 17 printf("%d",ans); 18 }
2048
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int TT=998244353,N=1e5+5; 4 long long n,cnt,sum,p[N],f[2050]; 5 6 int main() { 7 n=read(); 8 p[0]=f[0]=1; 9 for(int i=1;i<=n;i++) { 10 int x=read(); 11 p[i]=(p[i-1]<<1)%TT; 12 if(x&(x-1)) continue; //x不是2的次幂 13 cnt++; 14 for(int j=2047;j>=x;j--) 15 f[j]=(f[j]+f[j-x])%TT; 16 } 17 for(int i=0;i<2048;i++) sum+=f[i],sum%=TT; 18 printf("%lld",p[n-cnt]*(p[cnt]-sum+TT)%TT); 19 }