AB水題。
C貪心構造。
分情況討論:
1、a == 0或b != 0 ,先處理b個的情況,可以利用2的冪次來構造,因為例如1,2,4,8,16......2的冪次序列滿足後一個總大於前面所有值之和,可以化成二進位驗證,在處理a
2、a != 0&& b==0,如果a==n-1&&b==0很明顯矛盾;否則就先處理a,再處理b,前面要有兩個1保證a情況
int main(){ int n,a,b; while(scanf("%d%d%d",&n,&a,&b) != -1){ int i,j; if(b!=0 || a==0){ int x = 1; printf("%d",x); for(i=0;i<b;i++){ x*=2; printf(" %d",x); } for(i=0;i<a;i++){ x++; printf(" %d",x); } for(i=0;i<n-a-b-1;i++){ printf(" %d",x); } } else {//b==0 && a!=0 if(a==n-1){ puts("-1"); } else { int x = 1; printf("%d",x); printf(" %d",x); for(i=0;i<a;i++){ x++; printf(" %d",x); } for(i=0;i<n-a-2;i++){ printf(" %d",x); } } } puts(""); } return 0;}
D機率dp
#define N 1001double dp[N][N][3];//0—princess win,1—dragon not win,2—jumpbool vis[N][N][3];double dfs(int w,int b,int k){ double ret = 0.0; if(w <= 0 && b <= 0)return 0.0; if(vis[w][b][k])return dp[w][b][k]; vis[w][b][k] = 1; if(k == 0){//princess win if(w)ret += 1.0*w/(w+b); if(b)ret += dfs(w,b-1,1)*1.0*b/(w+b); } else if(k == 1){//dragon not win if(w)ret += 0.0*w/(w+b); if(b)ret += dfs(w,b-1,2)*1.0*b/(w+b); } else if(k == 2){//jump if(w)ret += dfs(w-1,b,0)*1.0*w/(w+b); if(b)ret += dfs(w,b-1,0)*1.0*b/(w+b); } return dp[w][b][k] = ret;}int main(){ int w,b; while(scanf("%d%d",&w,&b) != -1){ memset(vis,0,sizeof(vis)); printf("%.10f\n",dfs(w,b,0)); } return 0;}
E裸dp。
題意是說有n層書架,每層放有k個值,問拿出m個值最大是多少,拿的時候要求是每層只能從兩邊一直往裡面拿出。
方法:做兩次dp,第一次將每行dp,設f[i][j]表示第i行取j個最大值,j<=m,轉移方程f[i][j] = max(f[i][j],suml[s] + sumr[t]){s+t=j};第二次對前i行做dp,設dp[i][j]表示前i行取j個最大值,j<=m,轉移方程dp[i][j] = max(dp[i][j],dp[i-1][j-k]+f[i][k])
最後dp[n][m]就是結果。
int a[101][101];int f[101][10001];//第i行取j個最大值,j<=mint dp[101][10001];//前i行取j個最大值,j<=mint suml[101];int sumr[101];int n,m;void dp1(int r){ int i,j; int cnt = a[r][0]; suml[0] = 0; for(i=1;i<=cnt;i++){ suml[i] = a[r][i]; suml[i] += suml[i-1]; } sumr[0] = 0; for(i=cnt;i>=1;i--){ sumr[cnt-i+1] = a[r][i]; sumr[cnt-i+1] += sumr[cnt-i]; } for(i=0;i<=cnt;i++){ if(i>m)break; for(j=0;j<i;j++){ int ll = j; int rr = i-j; f[r][i] = max(f[r][i],suml[ll] + sumr[rr]); f[r][i] = max(f[r][i],suml[rr] + sumr[ll]); } }}void dp2(){ int i,j,k; for(i=1;i<=n;i++){ for(j=0;j<=m;j++){ for(k=0;k<=min(j,a[i][0]);k++){ dp[i][j] = max(dp[i][j],dp[i-1][j-k]+f[i][k]); } } } printf("%d\n",dp[n][m]);}int main(){ while(scanf("%d%d",&n,&m) != -1){ int i,j,k; memset(f,0,sizeof(f)); memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++){ scanf("%d",&a[i][0]); for(j=1;j<=a[i][0];j++){ scanf("%d",&a[i][j]); } dp1(i); } dp2(); } return 0;}