标签:
E. Anya and Cubes
题意:n个数随便取,最多使得取得数里面的t个不超过k个变成其阶层的形式,使得最后和为s的方法数。
比赛的时候随便写了个暴力,就睡了。
此题用中途相遇法搞下,从中间折半,把左边搜到的值hash一下。在从右边搜,每次搜到一个S时,把hash表里值为 s - S且用的t不超过的k的的种类数相加.
赛后用map水过,注意用map<int,int> m; 用m[5] 判断 ,和m.count(5) ;判断5这个键值存在不存在时候,是有时间差距的,m[5]直接访问如果不存在,则会插入一个0进去,这样会多了许多无用的值。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <vector> #include <cmath> #include <queue> #include <map> #include <set> using namespace std; #define INF 1000000000 //typedef __int64 LL; typedef long long LL; int up; LL s; LL k, len1, len2; LL chart[100]; map<int, LL> m[30]; LL val; int a[100]; LL jie(int x) { LL ans = 1; for (int i = 1; i <= x; i++) ans *= i; return ans; } int gao(LL x) { for (int i = 1; i <= 100; i++){ if (jie(i)>x){ return i - 1; } } } void init() { for (int i = 1; i <= up; i++){ chart[i] = jie(i); } } void dfs(int x, int ans, LL sum) { if (x == len1 + 1){ //printf("%d %d\n",k-ans,sum); m[k - ans][sum]++; return; } dfs(x + 1, ans, sum); if (sum + a[x] <= s) dfs(x + 1, ans, sum + a[x]); if (a[x] <= up&&chart[a[x]] + sum <= s&&ans){ dfs(x + 1, ans - 1, sum + chart[a[x]]); } } void DFS(int x, int ans, LL sum) { if (x == len2 + 1){ //printf("%d %d\n",k-ans,sum); for (int i = 0; i <= ans; i++) if (m[i].count(s - sum)) val += m[i][s - sum]; return; } DFS(x + 1, ans, sum); if (sum + a[x + len1] <= s) DFS(x + 1, ans, sum + a[x + len1]); if (a[x + len1] <= up&&chart[a[x + len1]] + sum <= s&&ans){ DFS(x + 1, ans - 1, sum + chart[a[x + len1]]); } } int main() { int n; val = 0; cin >> n >> k >> s; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); up = gao(s); init(); len1 = n / 2; len2 = n - len1; dfs(1, k, 0); DFS(1, k, 0); cout << val << endl; return 0; }
Codeforces Round #297 (Div. 2)
标签:
原文地址:http://www.cnblogs.com/yigexigua/p/4380060.html