AtCoder Regular Contest 060

C - 高橋君とカード / Tak and Cards

dp。记dp[i][j]为选了i张牌,和为j的方案数。

#include<cstdio>
#include<iostream>
using namespace std;
long long dp[55][2505], ans;
int n, a, m;
int main() {
    scanf("%d%d", &n, &a); dp[0][0] = 1; m = a * n;
    for (int t, i = 1; i <= n; ++i) {
        scanf("%d", &t);
        for (int j = i; j; --j)
            for (int k = m; k >= t; --k)
                dp[j][k] += dp[j-1][k-t];
    } 
    for (int i = 1; i <= n; ++i) ans += dp[i][i*a];
    printf("%lld\n", ans);
    return 0;
}

D - 桁和 / Digit Sum

这题很妙啊!

一句话题意:一个数N在b进制下表示为。记。现在告诉你,请你求出满足条件的最小的,如果这样的不存在,请输出-1。

分为两种情况讨论。

时:

直接枚举

时:

显然。又因为。所以

是已知的,只需要枚举的因数即可。

#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
ll s, n, m;
ll f(ll b, ll n) {
    return n < b ? n : f(b, n / b) + n % b;
}
int main() {
    cin >> n >> s; m = sqrt(n) + 1;
    if (s > n) return puts("-1"), 0;
    if (s == n) return printf("%lld\n", s + 1), 0;
    for (ll i = 2; i <= m; ++i)
        if (f(i, n) == s) return printf("%lld\n", i), 0;
    ll b, q, res = 1e11; n -= s;
    for (ll p = 1; p * p <= n; ++p) {
        if (n % p == 0 ) {
            b = n / p + 1; q = s - p;
            if (q >= 0 && b >= 2 && q < b && p < b)
                res = min(res, b);
        }
    } printf("%lld\n", res == 1e11 ? -1 : res);
    return 0;
}

 

posted @ 2017-12-20 11:48  p0ny  阅读(238)  评论(0编辑  收藏  举报