TopCoder SRM 568

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40032278/article/details/82145227

div.1

T1

题意

现有n个盒子,每个盒子里分别有R个红球,G个绿球和B个蓝球。
可以进行一种把一个球从一个盒子放到另一个盒子的操作。
现要用这种操作使得每个盒子里都只有一种颜色的球。
求最小操作次数。若不能,输出-1.

思路

首先,把所有的球都放到假想的三个框中。代价为球的总数。
然后我们发现,每个框都有一种颜色的球不需要放到假想框中。这种颜色的球的数量要从总代价里扣除。
而因为假象的框不存在,所以我们实际上要在保证选多的同时,保证每种颜色至少有一个框是选他的。
这显然可以转化为一个DP过程

#include <bits/stdc++.h>
using namespace std;
int c[200],dp[200][10];
class BallsSeparating {
public:
int minOperations( vector <int> red, vector <int> green, vector <int> blue ) ;
};
int BallsSeparating::minOperations(vector <int> red, vector <int> green, vector <int> blue) {
    int n=red.size(),tot=0,i,j;
    memset(c,0,sizeof(c));
    if(n<3) return -1;
    for(i=0;i<n;i++) 
    {
        c[i]=max(red[i],max(green[i],blue[i]));
        tot=tot+red[i]+green[i]+blue[i];
    }
    memset(dp,0,sizeof(dp));
    dp[0][1]=red[0];
    dp[0][2]=green[0];
    dp[0][4]=blue[0];
    for(i=1;i<n;i++)
    {
        for(j=1;j<=7;j+=2) 
            dp[i][j]=max(dp[i][j],max(dp[i-1][j]+red[i],dp[i-1][j^1]+red[i]));
        for(j=2;j<=7;j++)
        {
            if(j&2) dp[i][j]=max(dp[i][j],max(dp[i-1][j]+green[i],dp[i-1][j^2]+green[i]));
        }
        for(j=4;j<=7;j++)
            dp[i][j]=max(dp[i][j],max(dp[i-1][j]+blue[i],dp[i-1][j^4]+blue[i]));
    }
    if(dp[n-1][7]<0) return -1;
    else return tot-dp[n-1][7];
}

T2

题意

Sum(A,P)= A [0,P [0]] + A [1,P [1]] + … + A [N-1,P [N-1]]
A [i,j]是第i行和第j列中A的元素 P是从0到N-1的整数的排列
如果Sum(A,P)总是等于相同的值而忽略了排列P的选择,则矩阵A符合要求
输出 这种矩阵的数量

div.2

T3

题意

有n张卡片 上面有一些数字,排序他们使得其为一个非递减序列,,在分类过程中将执行步骤1(卡组的随机播放)的预期次数。

思路

反着处理一个dp就好了。只需要思考,倒着取数的期望就是当前数/相同数+之前数-1。。。然后dp前排个序就好了。

#include <bits/stdc++.h>
using namespace std;
class ShuffleSort {
public:
double shuffle( vector <int> cards ) ;
};
double ShuffleSort::shuffle(vector <int> cards) {
    int n=cards.size(),i,x=0,tot,k;
    double ans=0.0;
    tot=n;
    sort(cards.begin(),cards.end());
    while(x<n)
    {
        k=0;
        for(i=x;i<n;i++)
            if(cards[i]==cards[x]) k++;
        x+=k;
        while(k>0)
        {
            ans=ans+(double)tot/k-1.0;
            tot--;
            k--;
        }
    }
    ans+=1.0;   
    return ans;
}

猜你喜欢

转载自blog.csdn.net/qq_40032278/article/details/82145227