HDU 2017 多校联合 Contest 5

1006 Rikka with Graph

题意:

给n个节点,选择m条边,使得$\sum_{i=1}^{n}\sum_{j=1}^{n}dist(i,j)$最小。

思路:

肯定所有的点直接是根节点的子节点的时候是最优的。然后判断m和n的关系。

include "bits/stdc++.h"
using namespace std;
typedef long long LL;
int main(int argc, char const *argv[])
{
    int T;
    LL n, m;
    scanf("%d",&T);
    while (T--) {
        scanf("%lld%lld", &n, &m);
        LL ans;
        if (m > n*(n - 1)/2) m = n*(n - 1)/2;
        if (m >= n - 1) 
            ans = n*(n-1)+(n*(n-1)/2-m)*2;
        else 
            ans = 2*m*m+(n-m-1)*(m+1)*2*n+(n-m-1)*(n-m-2)*n;
        printf("%lld\n", ans);
    }
    return 0;
}

1008 Rikka with Subset

题意:

给出了n个元素和他们的和m,还有组成的$2^n$个子集和的统计,数组b从0-m,表示子集和是下标的有几个,然后反推出n个元素。

思路:

这道题我的锅。positive 没有注意到,然后一直考虑0的贡献。然后竟然一直蜜汁超时。。。。。。。。

看到题解,以为用背包进行优化,结果大家的代码都是直接计算新元素的贡献。。。。。。。。。

无奈。我的代码都优化废了,按照大家的意思重新写一遍。。。

#include "bits/stdc++.h"
const int maxn = 15000;
using namespace std;
typedef long long LL;
int b[maxn], a[maxn], dev[maxn];
int ans[maxn];
int main(int argc, char const *argv[])
{
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m;
        scanf("%d%d", &n, &m);
        memset(dev, 0, sizeof(dev));
        for (int i = 0; i <= m; i++) scanf("%d", b+i);
        dev[0] = 1;
        int cnt = 0;
        for (int i = 1; i <= m; i++) {
            int res = b[i] - dev[i]; 
            for (int j = 1; j <= res; j++) {
                a[cnt++] = i;
                //从后向前算贡献,否则计算后面的贡献的时候新贡献会影响
                for (int k = m; k >= i; k--) {
                    dev[k] += dev[k - i];
                }
            }
        }
        printf("%d", a[0]);
        for (int i = 1; i < cnt; i++) {
            printf(" %d", a[i]);
        }
        printf("\n");
    }
    return 0;
}

1011 Rikka with Competition

题意:

有n个人参加比赛,他们的分值大于k的情况下分数高的人才会获胜,否则输赢是不定的。问最后有多少人可能赢

思路:

将n个人排序,第一次大于K之前的数的个数即为答案。

#include "bits/stdc++.h"
using namespace std;
int a[100010];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--) {
        int N, K;
        int ans = 1;
        scanf("%d%d",&N, &K);
        for(int i = 0; i < N; i++) scanf("%d", a+i);
        sort(a, a + N);
        for(int i = N - 1; i > 0; i--) {
            if((a[i] - a[i-1]) > K) break;
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2017-08-12 12:20  zprhhs  阅读(167)  评论(0编辑  收藏  举报
Power by awescnb