题意:求是否所有格子周围都有偶数个'o'
题解:暴力遍历即可。
题意:一个人有n个卡片,每个卡片上面有一个英文大写字母。另一个人从中取k张,每张卡片的价值是取出同种卡片的数量。
题解:统计每种卡片出现次数,排序从数量多的开始取。hack点为爆int。
题意:给出一个集合包含n个数,进行两种操作。一种是:将集合给A,集合内所有数的和加到结果中,将集合给B。另一种是:如果B接到的集合只含一个元素,丢弃。否则将集合任意分成两份,分别给A。求最大结果。
题解:画了几种情况发现每次去掉最小的结果最大。写了,过了。
代码:
题意:一棵树,顶点分为黑白两种。删去一些边,使得形成的每棵新树有且只有一个黑点。求删边的可能数。
官方题解:
Fill a DP table such as the following bottom-up: DP[v][0] = the number of ways that the subtree rooted at vertex v has no black vertex. DP[v][1] = the number of ways that the subtree rooted at vertex v has one black vertex. The recursion pseudo code is folloing: DFS(v): DP[v][0] = 1 DP[v][1] = 0 foreach u : the children of vertex v DFS(u) DP[v][1] *= DP[u][0] DP[v][1] += DP[v][0]*DP[u][1] DP[v][0] *= DP[u][0] if x[v] == 1: DP[v][1] = DP[v][0] else: DP[v][0] += DP[v][1] The answer is DP[root][1].
PS:当时只推出了dp[v][1] *= dp[u][0];后面说什么也没推出来,太弱啊……
代码:
// _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\____ // . ' \\| |// `. // / \\||| : |||// \ // / _||||| -:- |||||- \ // | | \\\ - /// | | // | \_| ''\---/'' | | // \ .-\__ `-` ___/-. / // ___`. .' /--.--\ `. . __ // ."" '< `.___\_<|>_/___.' >'"". // | | : `- \`.;`\ _ /`;.`/ - ` : | | // \ \ `-. \_ __\ /__ _/ .-` / / // ======`-.____`-.___\_____/___.-`____.-'====== // `=---=' // // ............................................. // 佛祖保佑 永无BUG // 佛曰: // 写字楼里写字间,写字间里程序员; // 程序人员写程序,又拿程序换酒钱。 // 酒醒只在网上坐,酒醉还来网下眠; // 酒醉酒醒日复日,网上网下年复年。 // 但愿老死电脑间,不愿鞠躬老板前; // 奔驰宝马贵者趣,公交自行程序员。 // 别人笑我忒疯癫,我笑自己命太贱; #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #include <string> using namespace std; #define For(i,a) for(i=0;i<a;i++) #define Foru(i,a,b) for(i=a;i<=b;i++) #define Ford(i,a,b) for(i=a;i>=b;i--) #define clr(ar,vel) memset(ar,vel,sizeof(ar)) #define PB push_back typedef long long ll; const int maxint = 0x7fffffff; const ll maxll = 1LL<<60; const int mod = 1000000007; const double EPS = 1e-10; vector<int> vi[100010]; int vel[100010], vis[100010]; int dp[100010][2]; //0:不全脱离 ; 1:全脱离; inline int dfs(int n){ // cout << n << endl; int flag = 0; ll zero = 1, one = 0; for(int i = 0; i < vi[n].size(); i ++){ int nxt = vi[n][i]; if( vis[nxt] ) continue; vis[nxt] = 1; dfs( nxt ); one *= dp[nxt][0]; one += zero*dp[nxt][1]; zero *= dp[nxt][0]; one %= mod; zero %= mod; } dp[n][0] = zero; dp[n][1] = one; if( vel[n]) dp[n][1] = dp[n][0]; else dp[n][0] += dp[n][1]; dp[n][1] %= mod; dp[n][0] %= mod; } int main(){ int n; cin >> n; memset(vis, 0, sizeof(vis)); memset(dp, 0, sizeof(dp)); for(int i = 0; i < n; i ++) vi[i].clear(); for(int i = 1, x; i < n; i ++){ cin >> x; vi[x].push_back(i); // vi[i].push_back(x); 一开始建的无向边,wa了 看人家都是有向的注销了,过了 } for(int i = 0; i < n; i ++) cin >> vel[i]; dfs(0); // cout << "can solve" << endl; cout << dp[0][1]%mod << endl; return 0; }