Codeforces 1132

链接:http://codeforces.com/contest/1132


A - Regular Bracket Sequence - [水]

题解:首先 "()" 这个的数量多少是没有关系的,但是 "((" 和 "))" 的数量必须是相等的,再然后如果存在 ")(" 的话,"((" 和 "))" 的数目就必须要大于零。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int a,b,c,d;
int main()
{
    cin>>a>>b>>c>>d;
    if(a==d)
    {
        if(c>0 && a==0 && d==0) cout<<0<<endl;
        else cout<<1<<endl;
    }
    else cout<<0<<endl;
}

B - Discounts - [水]

题意:有 $n$ 块巧克力,每个价格为 $a[i]$,你必须把它们都买完。现在你有 $m$ 张优惠券,一张优惠券可以使你买任意 $q[i]$ 块巧克力并让你免去其中最便宜的那块巧克力的钱,剩下的都要全款买下。你要给出用每张优惠券买完所有巧克力的最少花费。

题解:很显然,如果一张优惠券只能买一块巧克力是最好的,能免去最贵的那块巧克力的钱;能买两个的次之,能免去次贵的巧克力的钱;以此类推。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+10;
int n,m,a[maxn];
int main()
{
    scanf("%d",&n);
    ll sum=0;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]), sum+=a[i];
    sort(a+1,a+n+1,greater<int>{});
    scanf("%d",&m);
    for(int i=1,q;i<=m;i++)
    {
        scanf("%d",&q);
        printf("%I64d
",sum-a[q]);
    }
}

C - Painting the Fence- [前缀和优化]


D - Stressful Training - [二分+贪心+优先队列]


E - Knapsack - [DFS]

网上看题解,居然可以搜过去?有点神仙啊……

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll w,a[10],ans;
void dfs(int p,ll x)
{
    if(p==9)
    {
        ans=max(ans,x);
        return;
    }
    ll v=min((w-x)/p,a[p]);
    for(int t=9;t>0;t--) dfs(p+1,x+max(0LL,(v--)*p));
}
int main()
{
    cin>>w;
    for(int i=1;i<=8;i++) cin>>a[i];
    dfs(1,0);
    cout<<ans<<endl;
}

F - Clear the String - [区间DP]

题解:设 $f[l][r]$ 是消除 $[l,r]$ 区间所花的最少次数,对于每次更新:

1、如果 $s[l]=s[r]$,$f[l][r]=min(f[l][r],f[l+1][r−1]+1)$;

2、如果 $s[l] eq s[r]$,$f[l][r]=min(f[l][r],min(f[l+1][r],f[l][r−1])+1)$

3、枚举中间点 $k=l sim r$,$f[l][r]=min(f[l][r],f[l][k]+f[k][r]−1)$,这样的话 $k$ 这个点删了两次,所以要减一,因为 $l,k,r$ 可能被同时删去,所以要这样转移。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=505;
int n;
char s[maxn];
int f[maxn][maxn];

int main()
{
    cin>>n;
    scanf("%s",s+1);

    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++) f[i][i]=1;
    for(int len=2;len<=n;len++)
    {
        for(int i=1,j=i+len-1;j<=n;i++,j++)
        {
            f[i][j]=INF;
            if(s[i]==s[j]) f[i][j]=min(f[i][j],f[i+1][j-1]+1);
            else f[i][j]=min(f[i][j],min(f[i+1][j],f[i][j-1])+1);
            for(int k=i;k<=j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k][j]-1);
        }
    }
    cout<<f[1][n]<<endl;
}
原文地址:https://www.cnblogs.com/dilthey/p/10486637.html