AtCoder Beginner Contest 044 C D
C
题目
题目大意
在n张牌中有多少种选法,可以使这几张牌的平均值为A
思路
dp
有一说一dp还真的是我的弱项
对于这道题我的想法是2^25的二进制暴力相加之后meet in the middle,但是因为最后的组合数学不大会,而且复杂度比较迷幻,所以放弃了
那么这一题给我最大的教育就是,以后对于要选取多少个数字的时候,如果复杂度允许,可以考虑揹包,dp
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
const int MAXN = 55;
ll a[MAXN];
ll dp[55][55*55];
int main()
{
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n, A;
cin >> n >> A;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
}
dp[0][0] = 1;
for(int i = 1; i <= n; i++)
{
for(int j = i; j > 0; j--)
{
for(int k = A * n; k >= a[i]; k--)
{
dp[j][k] += dp[j - 1][k - a[i]];
}
}
}
ll ans = 0;
for(int i = 1; i <= n; i++)
{
ans += dp[i][i *A];
}
cout << ans << endl;
}
D
题目
思路
不得不说真的妙啊
受教了
数论nb
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
ll f(ll b, ll n)
{
ll ans = 0;
while(n)
{
ans += n % b;
n /= b;
}
ans += n;
return ans;
}
int main()
{
// freopen("in.txt", "r", stdin);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n, s;
cin >> n >> s;
ll b = -1;
if(s > n)
{
cout << -1 << endl;
}
else if(s == n)
{
cout << n + 1 << endl;
}
else
{
for(ll i = 2; i <= sqrt(n) + 1; i++)
{
if(f(i, n) == s)
{
b = i;
break;
}
}
if(b != -1)
{
cout << b << endl;
return 0;
}
if(b == -1)
{
for(ll i = 1; i <= sqrt(n - s) + 1; i++)
{
if((n - s) % i == 0)
{
ll x1 = i;
ll x0 = s - x1;
ll tmpb = (n - s) / i + 1;
if(x1 < tmpb && x0 < tmpb && x0 >= 0 && tmpb >= 2)
{
if(b == -1) b = tmpb;
else
b = min(b, tmpb);
}
}
}
cout << b << endl;
}
}
}