20170715

来源:互联网 发布:vb调用matlab的dll 编辑:程序博客网 时间:2024/06/10 16:28


T1:

Alice 和 Bob 有一个长度为2n的数。现在他们要在这个数字上玩游戏。他们分别要从 2n 个位中取出 n 个位组成自己的幸运值。每一回合,Alice 或 Bob 把数字最左边的那一位拿来放在自己幸运值

的最末位。在第 i 轮操作过后,被选取的数位(原数的第i位)会从原数中消失。现在 Alice 和 Bob 想要使得他们两个幸运值的和尽可能大。请求出这个值。

自己想的选数: 

每次在可选的范围内选择最大的数

#include<bits/stdc++.h>using namespace std;int a[50],n,w=0,pos,tot;bool ex[50];long long ans=0;inline void work(){ans=ans*10;++w;for(int i=1;i<=n*2;++i){if(ex[i]==false){ans+=a[i];ex[i]=true;break;}}int maxn=-1;for(int i=1;i<=n*2;++i){if(2*n-i>=n-w&&i>=pos){if(ex[i]==false&&a[i]>maxn)maxn=a[i];}}for(int i=1;i<=n*2;++i){if(2*n-i>=n-w&&i>=pos){if(a[i]==maxn&&ex[i]==false){ex[i]=true;ans+=a[i];pos=i;break;}}}if(w==n) return;work();}int main(){//freopen("hello.in","r",stdin);//freopen("hello.out","w",stdout);scanf("%d",&n);for(int i=1;i<=2*n;++i) scanf("%1d",&a[i]);work();cout<<ans;return 0;}

标算:

动态规划 f[i][j]:当前位置选择i个数到第一个数中,选择i个数到第二个数中,f[i][j]=两数之和。

#include<bits/stdc++.h>using namespace std;int n;int a[50];long long f[20][20],s[50];int main(){scanf("%d",&n);for(int i=1;i<=2*n;++i) scanf("%1d",&a[i]);s[n]=1;for(int i=n-1;i>=1;--i) s[i]=s[i+1]*10;for(int i=1;i<=n;++i) f[i][0]=f[i-1][0]+a[i]*s[i],f[0][i]=f[i][0];for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)f[i][j]=max(f[i-1][j]+a[i+j]*s[i],f[i][j-1]+a[i+j]*s[j]);cout<<f[n][n];return 0;}