牛客OI周赛

OI周赛15

B-三角形:动态规划O(n*m*10000)

大意:
给n个背包,第i个背包有mi个物品的价值,从这n个背包中各取一个物品,总价值为这n个物品的价值和,求总价值前k的总价值和。
思路:
从背包中取物品,每个背包中的物品必取一个,由此联想的用dp来做。
先找状态:因为要求总价值前k的和,并且从数据上看来,一次选完后总价值不会超过10000,那就从1-10000判断能否组合出来,能组合出来又有多少种组合方式。所有问题就变成了组合成某个数的方法数。
                  所有找到状态有dp[i][j] 表示前i个背包种获得价值为j的方法数。
状态转移:dp[i][j] = dp[i-1][j-x]
初值:dp[0][0] = 1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <queue>
#include <string.h>
#include <cmath>
#include <bitset> 
#include <set>
#include <map>
#include <list>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500005;
const ll ds = 1e15+7;
const double p1 = 3.141592653589793238462643383;
const ll res = 233;

using namespace std;

int dp[105][10005];//dp[i][j]前i个背包中获得价值为j的种类数 
int main()
{
	int n,k,m,x;
	cin >> n >> k;
	dp[0][0] = 1;
	for(int i = 1; i <= n; i++){
		cin >> m;
		for(int j = 1; j <= m; j++){
			cin >> x;
			for(int t = x; t <= 10000; t++){
				dp[i][t] += dp[i-1][t-x];
			}
		}
	} 
	int cnt = 0;
	int ans = 0;
	for(int i = 1; i <= 10000; i++){
		if(dp[n][i]) {
			if(cnt+dp[n][i] > k){
				ans += (k-cnt)*i;
				break;
	    	}
	    	else{
	    		cnt += dp[n][i];
		    	ans += dp[n][i]*i;
			}
		}
	}
	cout << ans << endl;
 	return 0;
}

OI周赛14

C-tree:树形dp

大意:
给定一个n个节点,n-1条边的树,根节点可以任意选择,求各点深度之和的最小值。
思路:
假设以dp[i]表示以节点i为根节点的深度之和,size[i]表示以i为根节点的子树大小,如果我们已知以某个点u作为根节点的各点深度之和,那么以该点的某个孩子节点v作为根节点的各点深度之和为
dp[v] = dp[u] + n - 2*size[v],因为孩子节点v的子树上的节点到v的深度为到节点u的深度减一,其它节点深度加一,我们已知节点v的子树的小为size[v],每个节点深度减一,总共size[v]个节点,所以减去size[v],剩余其它节点为n-size[i],所以dp[v] = dp[v] - size[v]+n-size[v] = dp[u] + n - 2*size[v].
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <queue>
#include <string.h>
#include <cmath>
#include <bitset> 
#include <set>
#include <map>
#include <list>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500005;
const ll ds = 1e15+7;
const double p1 = 3.141592653589793238462643383;
const ll res = 233;

using namespace std;

vector<int>a[1000005];
int size[1000005],h[1000005],n,u,v;
ll dp[1000005],ans = 0;
void dfs1(int s,int f)
{
	int l = a[s].size();
	for(int i = 0; i < l; i++){
		int v = a[s][i];
		if(v == f) continue;
		h[v] = h[s] + 1;
		ans += h[v];
		dfs1(v,s);
		size[s] += size[v];
	}
	size[s] += 1;
}

void dfs2(int s,int f)
{
	ans = min(ans,dp[s]);
	int l = a[s].size();
	for(int i = 0; i < l; i++){
		int v = a[s][i];
		if(v == f) continue;
		dp[v] = dp[s] + n - 2*size[v];
		dfs2(v,s);
	//	ans = min(ans,)
	}
}

int main()
{
	cin >> n;
	for(int i = 1; i < n; i++){
	    cin >> u >> v;
	    a[u].push_back(v);
	    a[v].push_back(u);
	}
	dfs1(1,-1);
	//cout << ans << endl;
	dp[1] = ans;
	dfs2(1,-1);
	cout << ans << endl;
//	for(int i = 1; i <= n; i++){
//		cout << h[i] << " ";
//	}
 	return 0;
}

D-talk:动态规划

https://ac.nowcoder.com/acm/contest/4479/D
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <queue>
#include <string.h>
#include <cmath>
#include <bitset> 
#include <set>
#include <map>
#include <list>
#define ull unsigned long long
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500005;
const ll ds = 1e15+7;
const double p1 = 3.141592653589793238462643383;
const ll res = 233;

using namespace std;

double f[100005],p[100005];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i = 1; i <= n; i++) scanf("%lf",&p[i]);
	f[0] = 0.0;
	f[1] = 0.0;
	for(int i = 2; i <= n+1; i++){
		f[i] = (f[i-1]+1+(p[i-1]-1)*f[i-2]) / p[i-1];
	}
	printf("%.3lf\n",f[n+1]);
 	return 0;
}








全部评论

相关推荐

01-15 13:52
已编辑
河南大学 Java
六年要多久:标准头像,不吃香菜😂
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
02-14 11:10
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务