暑期集训 Contest 2

Glory And String

 

时间限制: 1 Sec  内存限制: 128 MB

 

题目描述

输入

First line is the number of strings T, the T lines follow, each line describe a string Glory needs to operate.The total length of strings won't exceed 5,000 and consist of only lower-case characters.The length of each string won't exceed 2,000.

输出

样例输入

3
aaaab
abcde
abb

样例输出

1
4
1

把原串反过来跟原串做一次最长公共子序列,原串总长减去最长公共子序列就是答案。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 5 * 1e3 + 5;
int dp[2][maxn];
char a[maxn],a1[maxn],c[maxn];
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        int ans = -1;
        scanf(" %s",a + 1);
        strcpy(c,a + 1);
        n = strlen(c);
        for(int i = 0;i <= n + 1; ++i) dp[0][i] = dp[1][i] = 0;
        for(int i = 1;i <= n; ++i) a1[i] = a[n + 1 - i];
        a1[0] =' ',a1[n + 1] = '\0';
        for(int i = 1;i <= n; ++i)
        {
            for(int j = 1;j <= n; ++j)
            {
                if(a[i] == a1[j]) dp[i % 2][j] = dp[(i - 1) % 2][j - 1] + 1;
                else dp[i % 2][j] = max(dp[(i - 1) % 2][j],dp[i % 2][j - 1]);
                ans = max(ans,dp[i % 2][j]);
            }
        }
        printf("%d\n",n - ans);
    }
    return 0;
}

W老师的玩具

时间限制: 2 Sec  内存限制: 128 MB

题目描述

由于不小心让W老师在某道题上卡了十几发,A给W老师买了个玩具以表示歉意.

这个玩具可以看做一个多重集
最初,集合中只有一个元素0
每一轮,W老师会操作其中的每一个元素(设当前操作的为x)执行以下三种操作之一:
   
    1.  x=x+1
    2.  x分裂成两个非负整数a,b 即x=a+b,且a>=0,b>=0    
    3.  什么也不做

W老师玩了很久之后,已经不记得自己玩了多少轮了.

他很好奇自己最少玩多少轮才能把集合从开始变成现在的状态.

于是他把这个任务交给了A,如果A能找到答案他就会选择原谅他.但是A实在是太菜了,你能帮帮A吗?

输入

第一行,一个整数N,表示最终集合的大小

第二行为N个非负整数,表示最终集合的每一个元素

输出

一行,W老师最少玩的轮数

样例输入

4
1 1 1 1

样例输出

3

提示

单组数据

N<=1,000,000

0<=集合里的数字<=1,000,000

 

样例解释

第一轮:

0分裂成0 0

第二轮

0 0中每个0分裂成两个0,得到0 0 0 0

第三轮

每个0+1,得到1 1 1 1

逆序模拟一下即可,代码中体会吧。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn];
bool cmp(int x,inty)
{
    returnx > y;
}
int main()
{
    int n;
    scanf("%d",&n);
    a[0] = -1;
    for(int i = 1;i <= n; ++i) scanf("%d",&a[i]);
    sort(a + 1,a + n + 1,cmp);
    int ans = 0;
    int loc = n,num0 = 0;
    int temp = a[n],cal = a[n];
    while(loc > 0)
    {
        temp = a[loc] - a[loc + 1];
        for(int i = 0;loc > 0 && i < temp && num0 > 1; ++i)
        {
            if(num0 & 1) ++num0;
            num0 >>= 1;
        }
        ans += temp;
        while(a[loc] == a[loc - 1]) --loc, ++num0;
        ++num0;
        --loc;
    }
    while(num0 > 1)
    {
        if(num0 & 1) ++num0;
        num0 >>= 1;
        ++ans;
    }
    printf("%d\n",ans);
    return 0;
}

尧老师要教孩子玩球球

 

时间限制: 2 Sec  内存限制: 128 MB

 

题目描述

尧老师总是被他女朋友抱怨:还在玩ACM,玩个球啊!所以今天他和他的孩子要去房顶玩球。他们有 n 个球,半径分别为 ri。现将它们完全装入了内径为 R 的烟囱(假设烟囱内部为圆柱),问烟囱高最小为多少。

输入

第一行包含一个整数 n (0 <= n <= 18)。

第二行包含 n 个整数 ri (0 < ri <= 1e4)。.

第三行包含一个整数 R(max(ri)<= R < 2 * min( ri ))。

输出

输出烟囱最小高度,保留两位小数。

样例输入

2
2 3
3

样例输出

9.90

正解是DP,打表找规律侥幸过了。。。规律是重新排序,把大的依次往两边放,从最大的开始,第一个最左边,第二个最右边,依次往中间靠,放完了都算一下就是答案。需要注意的是根据他的条件可以判断出一层只能放一个球,这样很大程度上简化了问题。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 20;
double a[maxn],b[maxn];
bool cmp(double x,double y)
{
    return x > y;
}
int main()
{
    int n;
    double R;
    scanf("%d",&n);
    if(n == 0)
    {

        printf("%.2f\n",0);
        return 0;
    }
    for(int i = 0;i < n; ++i) scanf("%lf",&a[i]);
    scanf("%lf",&R);
    sort(a,a + n,cmp);
    double ans = 0;
    int l = 0,r = n - 1,cou = 0;
    while(l <= r)
    {
        if(cou & 1) b[r--] = a[cou++];
        else b[l++] = a[cou++];
    }
    ans = ans + b[0] + b[n - 1];
    for(int i = 0;i < n - 1; ++i)
    {
        ans = ans +sqrt(4 * R * (b[i] + b[i + 1] - R));
    }
    printf("%.2f\n",ans);
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值