CF每日一练(2.11)

CF-1114

A. Got Any Grapes?

skip

B. Yet Another Array Partitioning Task

  • 将n个数分成连续的k组,使得每组的前m大的数字的总和最大。
  • 首先可以想到肯定可以包含n个数中前 m*k 大的数。所以可以先将他们标记,然后扫一遍确定每组的端点即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,k;
struct node{
    int x;
    int id;
}a[200010];
int v[200010];
bool cmp(node a,node b){
    return a.x>b.x;
}
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].x);
        a[i].id = i;
    }
    sort(a+1,a+n+1,cmp);
    ll sum = 0;
    for(int i=1;i<=m*k;i++){
        v[a[i].id] = 1;
        sum += a[i].x;
    }
    vector<int> ans;
    int num = 0;
    for(int i=1;i<=n;i++){
        if(v[i])num++;
        if(num==m){
            ans.push_back(i);num=0;
            if(ans.size()==k-1)
                break;
        }
    }
    cout<<sum<<endl;
    for(int i=0;i<k-1;i++)
        cout<<ans[i]<<‘ ‘;
    puts("");
    return 0;
}

C. Trailing Loves (or L‘oeufs?)

  • $ n! = p_1^{x_1} \cdot p_2^{x_2}\cdots p_m^{x_m} \cdot Q$
  • \(b = p_1^{y_1} \cdot p_2^{y_2} \cdots p_m^{y_m}\)

分解n!的质因数复杂度为 O(log N)。所以我们可以将b分解质因数,对于质因数\(p_i\),计算n!含有多少个质因子\(p_i\) (设\(x_i\)) ,则该质因子下答案为 \(\lfloor x_i/y_i \rfloor\) , 最终\(ans = min \{ \lfloor x_1/y_1 \rfloor \cdots \lfloor x_m/y_m\rfloor \}\)

  • 计算n!中含有多少个\(p_i\) 时,可以这样计算:

    • 首先在1到n的排列中肯定有\(\lfloor n/p_i \rfloor\)个包含质因子\(p_i\)的数,同理也有\(\lfloor x/{p_i^2}\rfloor\) 个含有两个\(p_i\)的数,不过其中的一个质因子已经在\(\lfloor n/p_i \rfloor\)中统计过,所以只需要再统计第二个质因子,即累加上\(\lfloor x/{p_i^2}\rfloor\),而不是\(2*\lfloor x/{p_i^2}\rfloor\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = LONG_LONG_MAX;
ll n,b;
ll calc(ll p,ll cnt){
    //res为上述xi
    ll res = 0,base = 1;
    for(;base<=n/p;){
        base*=p;
        res += n/base;
    }
    /*写成下面这样会爆
    for(base=x;base<=n;base*=x){
        res += n/base;
    }*/
    return res/cnt;
}
int main(){
    cin>>n>>b;
    ll ans = inf;
    //分解质因数
    for(ll i=2;i*i<=b;i++){
        if(b%i==0){
            ll cnt = 0;//cnt为上述yi
            while(b%i==0)b/=i,cnt++;
            ans = min(ans,calc(i,cnt));
        }
    }
    if(b>1) ans = min(ans,calc(b,1));
    cout<<ans<<endl;
}

D. Flood Fill

  • (又是一个没见过的区间DP,题解里面说可以倒过来LCS,相当于求最长回文子序列,不过我还没搞懂
  • d[i][j][0]表示区间[i,j]所有数字与a[i]相同时所需要的最少改变次数,d[i][j][1]表示与a[j]相同。复杂度为\(O(n^2)\)
  • 每次转移只能向左或者向右移动一格,细节看代码吧
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int n;
int a[5050];
int dp[5050][5050][2];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    if(n==1){
        puts("0");return 0;
    }
    memset(dp,0x3f,sizeof dp);
    for(int i=1;i<=n;i++)dp[i][i][0] = dp[i][i][1] = 0;
    for(int i=n;i>=1;i--){
        for(int j=i;j<=n;j++){
            for(int k=0;k<2;k++){
                //c为标准
                int c = k==0?a[i]:a[j];
                if(j<n)
                    dp[i][j+1][1] = min(dp[i][j+1][1],dp[i][j][k]+(a[j+1]==c?0:1));
                if(i>1)
                    dp[i-1][j][0] = min(dp[i-1][j][0],dp[i][j][k]+(a[i-1]==c?0:1));
            }
        }
    }
    cout<<min(dp[1][n][0],dp[1][n][1])<<endl;
}

原文地址:https://www.cnblogs.com/chd-acm/p/10362925.html

时间: 2024-07-31 17:12:55

CF每日一练(2.11)的相关文章

CF每日一练(2.9)

CF-1013 A. Piles With Stones 比较两个序列的和,因为只能拿走或者不拿,所以总数不能变大. B. And 答案只有 -1,0,1,2几种可能,所以对于每一种答案都暴力扫一次是可以的 或者对于每个 \(a_i\) ,将\(a_i\) 标记加一,如果\(a_i \neq a_i\& x\) ,将\(a_i\&x\) 用另一个数组标记加一.然后整体扫一次就可以了 #include <bits/stdc++.h> using namespace std; in

CF每日一练(2.10)

CF-1093 1093A - Dice Rolling 输出x/2即可 #include<bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while (t--) { int x; cin >> x; cout << x / 2 << endl; } return 0; } 1093B - Letters Rearranging 当且仅当字符串中所有字符都相同时,

每日一小练——快速Fibonacci数算法

上得厅堂,下得厨房,写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练! 题目:快速Fibonacci数算法 内容:先说说Fibonacci数列,它的定义是数列:f1,f2....fn有如下规律: 尝试寻找快速的求出fn的方法 我的解法:上来没多想,打开vs2013就敲了起来,问题果然很简单,分分钟就超神..奥,不对就解决了! 其实题目中就给出了这个算法的递归形式,所以首先我想到的是递归解法,不过因为求解快速方法在递归之前,我编写了一个非递归的算法 #include <iostream> usi

每日一小练——等值首尾和

上得厅堂,下得厨房,写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练! 题目:等值首尾和 内容: 假设有一个数组x[],它有n个元素,每一个都大于零:称x[0]+x[1]+...+x[i]为前置和,而x[j]+x[j+1]+...+x[n-1]为后置和.试编写一个程序,求出x[]中有多少组相同的前置和后置和. 例如:x[]的元素是3,6,2,1,4,5,2,于是x[]的前置和有以下7个,即3,9,11,12,16,21,23:后置和则2,7,11,12,14,20,23; 于是11,12,23,

每日一小练——高速Fibonacci数算法

上得厅堂,下得厨房,写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练! 题目:高速Fibonacci数算法 内容:先说说Fibonacci数列,它的定义是数列:f1,f2....fn有例如以下规律: 尝试寻找高速的求出fn的方法 我的解法:上来没多想,打开vs2013就敲了起来,问题果然非常easy,分分钟就超神..奥,不正确就攻克了! 事实上题目中就给出了这个算法的递归形式,所以首先我想到的是递归解法,只是由于求解高速方法在递归之前,我编写了一个非递归的算法 #include <iostrea

HTML5每日一练之视频标签的应用

与音频一样,在过去,我们如果想在Web上播放视频,也是都是通过Flash来播放,同样并不是所有的浏览器都安装了Flash播放器插件,而现在我们在HTML5中,就能完全脱离Flash或其他的插件来播放视频了. video标签:   IE9 FireFox 5.0 Safari 5.5 Chrome 12 Opera 11.5 Mpeg4 √ × √ √ × Ogg × √ × √ √ WebM × √ × √ √ Ogg:带有 Theora 视频编码和 Vorbis 音频编码的 Ogg 文件MPE

ACM每日一练(猴子吃桃问题)

描述 有一堆桃子不知数目,猴子第一天吃掉一半,又多吃了一个,第二天照此方法,吃掉剩下桃子的一半又多一个,天天如此,到第m天早上,猴子发现只剩一只桃子了,问这堆桃子原来有多少个? (m<29) 输入 第一行有一个整数n,表示有n组测试数据(从第二行开始,每一行的数据为:第m天): 输出 每一行数据是桃子的总个数 样例输入 2 3 11 样例输出 22 6142 普通解法 分析:  倒推  前一天的桃子总数 与后一天的桃子总数关系 递推公式是 a[m-1]=(a[m]+1)*2; 我们可以通过循环m

WindowsAPI每日一练(1) MessageBoxA

WindowsAPI每日一练系列 :https://www.cnblogs.com/LexMoon/category/1246238.html WindowsAPI每日一练(1) WinMain 要跟计算机进行交互,就需要计算机显示信息给人看到,或者发出声音给人听到,然后人看到或听到相应的信息后,再输入其它信息给计算机,这样就可以让计算机进行数据处理,把结果显示给我们.现在就来编写一个最简单的Windows应用程序,让它提示一行文字给我们看到,这就是简单的目标. 1 #include <wind

CSS3每日一练之内容处理-嵌套编号

出处:http://www.w3cfuns.com/thread-5592229-1-17.html 1.大标题一   1.子标题   2.子标题   3.子标题2.大标题二   1.子标题   2.子标题3.大标题三   1.子标题   2.子标题   3.子标题 这种问题,你可能会觉得直接定义两个计数器,分别编号不就行了,于是就写出了如下代码: <!DOCTYPE HTML> <html> <head> <meta charset="gb2312&q