直接放代碼吧。數組
int n,k; int main() { n=read();k=read(); puts(k<=(n+1)/2?"YES":"NO"); return 0; }
int d[N];pair<int,int>s[10]; int main() { for(int i=1,u,v;i<=3;i++){ u=read();v=read(); s[i].first=u;s[i].second=v; d[u]++;d[v]++; } sort(s+1,s+3+1); for(int i=2;i<=3;i++)if(s[i]==s[i-1])return puts("NO"),0; for(int i=1;i<=4;i++)if(d[i]>=3)return puts("NO"),0; return puts("YES"),0; }
int main() { int k=read(),a=read(),b=read();ll ans=0; if(b<=a+2||k<=a-1)printf("%d\n",k+1); else{ k-=a-1;ans=a;if(k&1)k--,ans++; printf("%lld\n",ans+1ll*(k/2)*(b-a)); } return 0; }
zsy在一條\([0,L]\)的數軸上來回走路。
zsy能夠任選\([0,L]\)中的整點做爲起點和終點,而且zsy走路時只能在整數位置(\(0,1,2,...,L\))調整方向。
每當zsy向左或向右通過一條\([i,i+1]\ (i\in[0,L))\)的線段時,zsy就會往這條線段的中間放上一個球。
當zsy走完路後,yyb會來到這條數軸。她會進行若干次操做:打爆一個球或在一條線段的中間放上一個球。
如今給出數軸每條線段中間最終球的個數\(a_1,...,a_n\),求出zsy的一種行走方式,使得yyb的操做次數最小。spa
由於zsy能夠反覆橫跳來回地走,因此能夠把\(a_i\)減去若干個2,最後只剩下\(0,1,2\)三種狀態。
能夠知道對應簡化數組的一種最優方案裏zsy不會重複走過一條路超過2次。
既然是迴路問題,考慮插頭dp。
設\(f[i][j][k]\)表示考慮輪廓線到達\(i\),插頭有\(j\)個,已經用了\(k\)個單插頭的最少代價,
直接轉移便可。code
int n,t[N];ll suft[N],dp[N][3][3],ans; inline void upd(ll &a,ll b){a=a<b?a:b;} inline int calc(int x,int r){ if(r==0)return x; if(r==1)return x&1?0:1; if(r==2){if(!x)return 2;else return x&1?1:0;} } int main() { n=read();for(int i=1;i<=n;i++)t[i]=read(); for(int i=n;i;i--)suft[i]=suft[i+1]+t[i];ans=suft[1]; memset(dp,63,sizeof(dp));dp[0][0][0]=0; for(int i=0;i<=n;i++) for(int a=0;a<3;a++) for(int b=0;b<3;b++){ if(a==0){ upd(dp[i+1][a][b],dp[i][a][b]+t[i+1]); if(b!=2)upd(dp[i+1][a+1][b+1],dp[i][a][b]+calc(t[i+1],1)); upd(dp[i+1][a+2][b],dp[i][a][b]+calc(t[i+1],2)); } if(a==1){ if(b!=2)upd(ans,dp[i][a][b]+suft[i+1]); upd(dp[i+1][a][b],dp[i][a][b]+calc(t[i+1],1)); if(b!=2)upd(dp[i+1][a+1][b+1],dp[i][a][b]+calc(t[i+1],2)); } if(a==2){ upd(ans,dp[i][a][b]+suft[i+1]); if(b!=2)upd(dp[i+1][a-1][b+1],dp[i][a][b]+calc(t[i+1],1)); upd(dp[i+1][a][b],dp[i][a][b]+calc(t[i+1],2)); } } printf("%lld\n",ans); return 0; }
考慮給定行後選出列集合的方案數:
若是行的異或和不爲0,那麼總有一半的方案選出來異或和爲1,另外一半爲0,所以方案爲\(2^{m-1}\)
因而答案變成\(2^{m-1}S\),其中\(S\)表示行向量選出來的異或和不爲\(0\)的方案數。
求解選取行向量集合,使其異或和不爲0的方案數是一個經典問題:
考慮求出\(n\)個行向量的線性基,設其大小爲\(r\)。
若是僅選取線性基中的元素,顯然沒法使得異或和爲\(0\);
那麼考慮先選取不在線性基中的元素:
對於這樣的一組方案,在線性基中都有惟一的一種選取元素的方案,使得全部元素的異或和爲0.
所以\(S=2^n-2^{n-r}\)。class
int n,m,a[N][N],now[N],in[N],p[N][N],r; inline int poww(int a,int b){ int res=1; for(;b;b>>=1,a=1ll*a*a%mod) if(b&1)res=1ll*res*a%mod; return res; } int main() { n=read();m=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)a[i][j]=read(); for(int i=1;i<=n;i++){ memcpy(now,a[i],sizeof(now)); for(int j=1;j<=m;j++) if(now[j]){ if(in[j])for(int k=j;k<=m;k++)now[k]^=p[j][k]; else{in[j]=1;memcpy(p[j],now,sizeof(p[j]));r++;break;} } } printf("%lld\n",1ll*(poww(2,n)-poww(2,n-r)+mod)%mod*poww(2,m-1)%mod); return 0; }
考慮直接構造最終序列。由傳球方式能夠知道,第\(i(i\le n)\)個球只會在\(1-i\)我的的手中出現,後\(n\)個求隨意。
所以直接設\(f[i][j]\)dp,最後組合數乘一下便可。sort
char s[N];int n,dp[N][N],c[N][N],ans; inline void upd(int &a,int b){a+=b;if(a>=mod)a-=mod;} int main() { scanf("%s",s+1);n=strlen(s+1); for(int i=0;i<=n;i++) for(int j=c[i][0]=1;j<=i;j++)upd(c[i][j]=c[i-1][j],c[i-1][j-1]); dp[0][0]=1; for(int i=1;i<=n;i++) for(int j=0,c=s[i]-48;j<=i;j++){ if(j>=c-1)upd(dp[i][j],dp[i-1][j-c+1]); if(j>=c)upd(dp[i][j],dp[i-1][j-c]); } for(int i=0;i<=n;i++)upd(ans,1ll*dp[n][i]*c[n][i]%mod); printf("%d\n",ans); return 0; }