SDFZ夏令营考试(-)

正解DP
这里写图片描述


考试代码 ##Bfs

#include<cstdio>
#include<iostream>
using namespace std;
int q[100005];
bool isok[100005];
int n,ans,pos=0;
char s[100005];
int v[100005];
bool change;
void bfs(int k)
{
    int h=1,t=pos;
    while(h!=t)
    {   change=0;
        int maxn=0;int pis;//int len;if(k==pos)len=n-1;else len=q[i+1]; 
        for(int i=q[h];i<n;i++)
        {

            if(s[i]==')'&&!isok[i]&&v[i]>maxn)
            {
                maxn=v[i];change=1;pis=i;
            }

        }
        isok[pis]=1;
        //cout<<v[q[h]]<<" "<<maxn<<endl;
        if(change)ans+=v[q[h]]+maxn;

        h++;
    }
}
int main()
{
    freopen("bracket.in","r",stdin);freopen("bracket.out","w",stdout);
    scanf("%d",&n);
    cin>>s;
    for(int i=0;i<n;i++){
        if(s[i]=='(')
        q[++pos]=i;
        }
        //for(int i=1;i<=pos;i++)cout<<q[i]<<" ";
    for(int i=0;i<n;i++)scanf("%d",&v[i]);
    bfs(1);
    printf("%d\n",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}

错误原因:
做法:把左括号入队,去匹配最大的右括号
只注意了右括号的最优性,而忽略了左括号

  • 样例:
    -输入
    13
    ) ) ( ) ( ( ( ) ( ( ( ) )
    15 10 89 56 64 32 3 22 40 10 69 18 14
  • 输出
  • 372
  • 而考试程序输出:
  • 这里写图片描述

    修改:
    70分。。。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
int n,v[250002],f[2][2322];
char s[251312];
using namespace std;
int main()
{
      priority_queue<int>l,r;
    scanf("%d",&n);
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)scanf("%d",&v[i]);
    if(n<=2000)
    {
          f[0][0]=0;
    for(int i=1;i<=n;i++)f[0][i]=-92341215;
    //f[i][j],到第i个字符有j个未匹配的(,
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=n;j++)
        {//要注意边界条件。
            f[1][j]=f[0][j];
         if(s[i]==')'&&j<n//如果是),则上一个状态要匹配一个(,所以上                                                                                                                                            //个状态为f【i-1】【j+1】。但是不能从第n+1个状态转移过来。
            f[1][j]=max(f[1][j],f[0][j+1]+v[i]);
        if(s[i]=='('&&j)//反之亦然。
            f[1][j]=max(f[1][j],f[0][j-1]+v[i]);
        }
        for(int j=0;j<=n;j++)f[0][j]=f[1][j];
    }
    cout<<f[0][0];
    }
    else
    {
         int ans=0;
        for(int i=1;i<=n;i++)
        if(s[i]=='(')l.push(v[i]);
        else r.push(v[i]);

        while(!l.empty()&&!r.empty()&&* l.top()>0&&r.top()>0  *)
        {
            ans+=l.top()+r.top();
            l.pop();r.pop();
        }
        cout<<ans<<endl;
    }
  return 0;
}

后面贪心的问题
两个相加是正的就行改为

l.top()+r.top()>0

这里写图片描述
这里写图片描述

考试代码: ##Dfs

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,m;
int dx[]={1,0,-1,0},dy[]={0,-1,0,1};
int a[1005][1005];
bool ok[1005][1005],yes;
int ans;
struct node{
    int x1,y1,x2,y2;
}q[50005];
void dfs(int k,int x,int y,int step,int to)
{
    if(yes)return ;
    if(step==4)return ;
    if(x==q[k].x2&&y==q[k].y2){yes=1;return ;}
    else
    {
        for(int i=0;i<4;i++)
        {
            int tx=x+dx[i],ty=y+dy[i];
            if(tx>=1&&tx<=n&&ty>=1&&ty<=m)
            if((a[tx][ty]==0||a[tx][ty]==k)&&!ok[tx][ty])
            {
            if(to!=i)step++;//cout<<tx<<" "<<ty<<endl;
            ok[tx][ty]=1;         // cout<<a[tx][ty]<<endl;
            dfs(k,tx,ty,step,i);
            ok[tx][ty]=0;
            if(to!=i)step--;
            }
        }
    }
}
int main()
{
    freopen("linking.in","r",stdin);freopen("linking.out","w",stdout);
    int k,x,y,fx,fy;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d%d%d",&x,&y,&fx,&fy);
        a[x][y]=a[fx][fy]=i;
        q[i].x1=x,q[i].y1=y;
        q[i].x2=fx,q[i].y2=fy;
    }
    //cout<<a[2][1]<<endl;
    for(int i=1;i<=k;i++)
    {
        memset(ok,0,sizeof(ok));yes=0;
       dfs(i,q[i].x1,q[i].y1,1,0);
       if(yes)ans++;
   }
    cout<<ans<<endl;
    fclose(stdin);fclose(stdout);
    return 0;

}

这里写图片描述
这里写图片描述

考试代码: #无算法模拟

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,k,x;
int g(int x)
{
    int k=0;
    while(x%10==0)
    {
        x/=10;k++;
    }
    int sum=0;
    while(x)
    {
        int s;
        s=x%10;sum*=10;
        sum+=s;
        x/=10;
    }
    for(int i=1;i<=k;i++)sum*=10;
    return sum;
}
int f(int x)
{
    if(!x)return 0;
    if(x>0)
    {
        if(x<=g(x))return x-1;
        else return g(x);
    }
}
int fk(int x,int k)
{
    //if(x<0)return 0;
    if(x>=0)
    {
        if(k==0)return x;
        if(k>0)return f(fk(x,k-1));
    }
}
int main()
{
    freopen("linking.in","r",stdin);freopen("linking.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&k);
        printf("%d\n",fk(x,k));
    }
    fclose(stdin);fclose(stdout);
    //cout<<g(100);
    return 0;
}

错因:

总结:

猜你喜欢

转载自blog.csdn.net/k42946/article/details/81063554