好高骛远之SRM 544 DIV2

250pt

简单题,但很容易错。正确率只有19%

题意:某国正进行选举,选民有10000,不投票和多投票都算作弊。给定n个候选者的四舍 五入后的得票率,求是否有人在作弊。

算法:贪心

分析:求10000是否能组成该投票结果的所需最小人数和最大人数
写的时候只考虑小数点后一位,相当于考虑100010000人的话应该是小数点后两位

 

500pt

当时想到了,却证明不了也就不敢做,,后来还是不知道怎么证明

ADD:因为胶水可以无限使用,无论怎么切,只要切得次数一定,剩余的废料拼成的木板的长度也就一定

题意:需要dc块长度为dl的木板,在需要长度为al的木板最少的条件下,求切割的最少次

数,可用胶水粘合切下来的木板合成所需的

算法:贪心,数论

分析:首先切dc次肯定能获得足够的木板,但是在这个过程中切下来的多余部分肯定拼成所需的木板从而减少切割的次数

1,求出dlal的最小公倍数.lcm..即长度为lcm时可减少一次切割

2,总长度(dl*dc)除以lcm就是在整个切割过程中可以减少的次数c,

3,答案就等于dc-c

View Code
#include <cstdlib> 
#include <cctype> 
#include <cstring> 
#include <cstdio> 
#include <cmath> 
#include <algorithm> 
#include <vector> 
#include <string> 
#include <iostream> 
#include <sstream> 
#include <map> 
#include <set> 
#include <queue> 
#include <stack> 
#include <fstream> 
#include <iomanip> 
#include <bitset> 
#include <list> 
#include <strstream> 
using namespace std; 
#define REP(i,n) for(i=0;i<(n);++i) 
#define FOR(i,l,h) for(i=(l);i<=(h);++i) 
#define FORD(i,h,l) for(i=(h);i>=(l);--i) 
typedef vector<int> VI; 
typedef vector<double> VD; 
typedef long long LL; 

class BoardSplitting 
{ 
        public:
        int gcd(int a,int b){
            return b?gcd(b,a%b):a;
        } 
        int minimumCuts(int desiredLength, int desiredCount, int actualLength) 
        { 
            return desiredCount-(desiredLength*desiredCount/
            (actualLength*desiredLength/gcd(actualLength,desiredLength)));
        } 
        
 
}; 

 

1000pt

当时没看,即使看了也做不出来,临场发挥太差,线下做很容易

题意:给定四个数组,a[],b[],c[],d[].a[],b[]的末尾按任意顺序取数,直至取完,取出之后不放回,放到另两个空的数组e[],f[]之中,求有多少种放法使e[]等于c[]f[]等于d[]

算法:动态规划

分析:

1:如果a[]b[]的长度和不等于c[]d[]的,那么答案肯定为0

2,令d[i][j][k]表示a[]还剩i,b[]还剩j,c[]已放k个,那么d[]自然放了na-i+nb-h-k个,这种状态又有四种转移而来,a[i+1]->c[k],a[i+1]->d[na-i+nb-h-k],b[j+1]->c[k]b[j+1]->d[na-i+nb-h-k]

PS:Compile的时候Arema居然说内存超出100K,把 dp[][][]放到类中就过了。

View Code
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#define MAX 1000000007
using namespace std;

class AliceBobShuffle {
    public:
    int dp[51][51][51];
    int countWays(vector <int> AliceStart, vector <int> BobStart, vector <int> AliceEnd, vector <int> BobEnd);
    

};
int AliceBobShuffle::countWays(vector <int> AliceStart, vector <int> BobStart, vector <int> AliceEnd, vector <int> BobEnd) {
    int a[51],b[51],c[51],d[51];
    int i,j,k,na,nb,nc,nd;
    memset(dp,0,sizeof(dp));
    na=AliceStart.size();
    nb=BobStart.size();
    nc=AliceEnd.size();
    nd=BobEnd.size();
    if(na+nb!=nc+nd)
        return 0;
    for(i=na-1;i>=0;i--)
        a[i+1]=AliceStart[i];
    for(i=nb-1;i>=0;i--)
        b[i+1]=BobStart[i];
    for(i=0;i<nc;i++)
        c[i+1]=AliceEnd[i];
    for(i=0;i<nd;i++)
        d[i+1]=BobEnd[i];
    dp[0][0][0]=1;
    for(i=0;i<=na;i++)
        for(j=0;j<=nb;j++)
            if(i+j)
                for(k=0;k<=nc;k++)
                    if(i+j>=k)
                    {
                        if(i>0)
                        {
                            if(k>0&&a[i]==c[k])
                                dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k-1])%MAX;
                            if(i+j>k&&a[i]==d[i+j-k])
                                dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k])%MAX;
                        }
                        if(j>0)
                        {
                            if(k>0&&b[j]==c[k])
                                dp[i][j][k]=(dp[i][j][k]+dp[i][j-1][k-1])%MAX;
                            if(i+j>k&&b[j]==d[i+j-k])
                                dp[i][j][k]=(dp[i][j][k]+dp[i][j-1][k])%MAX;
                        }
                    }
    return dp[na][nb][nc];
}

 

 

原文地址:https://www.cnblogs.com/xchaos/p/2544987.html