Wannafly挑戰賽24-A,B,C
阿新 • • 發佈:2019-02-19
思路:對於大於1的奇數分析,對於3 可以分為1,2,然後2與其他偶數合併,總共2次;考慮最後的偶數也與其他偶數合併,那麼對於5可以分成 1,4 (2次)和 3,2 (4次),7和分為 1,6(2次),3,4(4次)和 5,2(6次)可以發現大於1的奇數的操作次數都是偶數次,那麼說明奇數對於結果是沒有影響的,只要對偶數個數考慮,當偶數個數為偶數是為Bob贏,為奇數則為 Alice贏,對於特殊情況,只有一個奇數時同樣成立,而全為 1時則是 Bob贏
Code :
#include<iostream> using namespace std; int main() { int n,s2=0,x,p=0; cin>>n; for(int i=0;i<n;++i) { cin>>x; if(x%2==0) ++s2; if(x>1) p=1; } string str="Alice"; if(!p||s2%2) str="Bob"; cout<<str<<endl; return 0; }
Code :
#include<iostream> #include<cstring> using namespace std; typedef long long LL; const int MAX_S=10000005; int p; int d[MAX_S]; int main() { int a,b; while(cin>>p){ memset(d,0,sizeof(d)); int s=3; for(int i=1;i<=p;s=s*3%p,++i) if(!d[s]) d[s]=i; else break; LL n=p-2,inv=1,ai=2; while(n){ if(n&1) inv=inv*ai%p; ai=ai*ai%p; n>>=1; } s=inv; int sum=p+1; for(int i=1;i<=p&&i<sum;s=s*inv%p,++i) if(d[s]&&sum>i+d[s]){ a=i; b=d[s]; sum=a+b; } cout<<a<<" "<<b<<endl; } return 0; }
易知在放置時操作多次其實和操作一次最終的效果是一樣的
dp[i][j] : 在第 i 個物品天平兩邊相差為 j 的最大收益,
dp[i][j] = max(dp[i][j], dp[i-1][j]); //不選的情況
dp[i][j+x] = max(dp[i][j+x], dp[i-1][j]+x); //同側
dp[i][abs(j-x)] = max(dp[i][abs(j-x)], dp[i-1][j]+x); //異側
Code :
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int MAX_N=105; const int MAX_S=100005; int n,m; int dp[MAX_N][MAX_S]; int main() { memset(dp, -1, sizeof(dp)); dp[0][0]=0; scanf("%d%d",&n,&m); for(int i=1,x;i<=n;++i) { scanf("%d",&x); for(int j=0;j<MAX_S;++j) { dp[i][j]=max(dp[i][j],dp[i-1][j]); if(j+x<MAX_S&&dp[i-1][j]!=-1){ dp[i][j+x]=max(dp[i][j+x],dp[i-1][j]+x); } if(dp[i-1][j]!=-1) dp[i][abs(j-x)]=max(dp[i][abs(j-x)],dp[i-1][j]+x); } } int ans=0; for(int i=0;i<=m;++i) ans=max(ans,dp[n][i]); printf("%d",ans); return 0; }