Codeforces Round #321 (Div. 2)

水 A - Kefa and First Steps

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/23 星期三 00:19:33
* File Name     :A.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
int a[N];

int main(void)    {
	int n;	scanf ("%d", &n);
	for (int i=1; i<=n; ++i)	{
		scanf ("%d", &a[i]);
	}
	int l = 1;
	int ans = 1;	int pre = a[1];
	for (int i=2; i<=n; ++i)	{
		if (a[i] >= pre)	{
			pre = a[i];	ans = max (ans, i - l + 1);
		}
		else	{
			pre = a[i];	l = i;
		}
	}
	printf ("%d
", ans);

    return 0;
}

  

尺取法 B - Kefa and Company

题意:每个朋友有他的金钱和友好程度,从朋友中选取一些人,问在贫富差距小于d的最大友好程度和为多少

分析:先按照m金钱从小到大排序,枚举每个起点看以这个人为最穷的人能得到的最大友好程度多少,然后是第二穷的人。。。。。复杂度O (nlogn),尺取法也叫two points ?

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/23 星期三 00:19:38
* File Name     :B.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
struct Friend	{
	int m, s;
	bool operator < (const Friend &r) const {
		return m < r.m;
	}
}f[N];

int main(void)    {
	int n, d, mn = INF, mx = -1;
	ll sum = 0;
	scanf ("%d%d", &n, &d);
	for (int i=1; i<=n; ++i)	{
		scanf ("%d%d", &f[i].m, &f[i].s);
		if (f[i].m > mx)	mx = f[i].m;
		if (f[i].m < mn)	mn = f[i].m;
		sum += f[i].s;
	}
	if (mx - mn < d)	{
		printf ("%I64d
", sum);	return 0;
	}
	sort (f+1, f+1+n);
	int l = 1, r = 2;
	ll ans = f[1].s;	sum = f[1].s;
	while (true)	{
		while (r <= n && f[r].m - f[l].m < d)	{
			sum += f[r++].s;
		}
		ans = max (ans, sum);
		if (r > n)	break;
		sum -= f[l++].s;
	}
	printf ("%I64d
", ans);

    return 0;
}

  

DFS C - Kefa and Park

题意:从根节点1出发,到底部的点的路径没有超过连续m个点有cat的个数为多少

分析:简单的深搜,记录走到当前点最大连续cat数,注意一些剪枝

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/23 星期三 00:19:41
* File Name     :C.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
vector<int> G[N];
int cat[N];
bool vis[N];
int n, m, ans;

void DFS(int u, int fa, int num)	{
	for (int i=0; i<G[u].size (); ++i)	{
		int v = G[u][i];
		if (vis[v] || v == fa)	continue;
		if (cat[v])	{
			if (num + 1 <= m)	{				//算上当前点,cat + 1
				if (G[v].size () == 1)	{		//到达底部
					vis[v] = true;	ans++;
				}
				else	{
					vis[v] = true;				//未到达底部
					DFS (v, u, num + 1);
				}
			}
			else	continue;					//条件不符,不往下艘
		}
		else	{
			if (num <= m)	{
				if (G[v].size () == 1)	{
					vis[v] = true;	ans++;
				}
				else	{
					vis[v] = true;
					DFS (v, u, 0);
				}
			}
			else	continue;
		}
	}
}

int main(void)    {
	scanf ("%d%d", &n, &m);
	for (int i=1; i<=n; ++i)	{
		scanf ("%d", &cat[i]);
	}
	for (int u, v, i=1; i<n; ++i)	{
		scanf ("%d%d", &u, &v);
		G[u].push_back (v);
		G[v].push_back (u);
	}
	DFS (1, 0, cat[1]);
	printf ("%d
", ans);

    return 0;
}

  

状态压缩DP D - Kefa and Dishes

题意:n道菜选择m道,每道菜有一个愉悦度,如果某些菜按照先后顺序吃还能得到额外的愉悦度,问最大愉悦度为多少

分析:其实就是一个DAG问题,数据范围18应该想到状压,我不熟悉以为数据范围太大,做不了。dp[mask][i] 表示当在mask集合状态下,最后是第i道菜的最大愉悦度为多少,状态转移方程:dp[(i|(1<<l))][l] = max (dp[i][j] + a[l] + g[j][l])  复杂度O(2n * n2).

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/23 星期三 01:49:58
* File Name     :D.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 18;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
int n, m, k;
ll dp[(1<<N)+10][N];
int a[N];
int g[N][N];

int main(void)    {
	scanf ("%d%d%d", &n, &m, &k);
	for (int i=0; i<n; ++i)	{
		scanf ("%d", &a[i]);
	}
	for (int u, v, c, i=1; i<=k; ++i)	{
		scanf ("%d%d%d", &u, &v, &c);
		if (g[u-1][v-1] < c)	g[u-1][v-1] = c;
	}
	int maxS = (1 << n);
	for (int i=0; i<n; ++i)	{
		dp[(1<<i)][i] = a[i];
	}

	for (int i=1; i<maxS; ++i)	{
		for (int j=0; j<n; ++j)	{
			if ((i & (1 << j)) == 0)	continue;
			for (int l=0; l<n; ++l)	{
				if ((i & (1 << l)) == 0)	{
					if (dp[(i|(1<<l))][l] < dp[i][j] + a[l] + g[j][l])	{
						dp[(i|(1<<l))][l] = dp[i][j] + a[l] + g[j][l];
					}
				}
			}
		}
	}
	ll ans = 0;
	for (int i=1; i<maxS; ++i)	{
		int cnt = 0;
		for (int j=0; j<n; ++j)	{
			if ((i & (1 << j)) != 0)	cnt++;
		}
		if (cnt == m)	{
			for (int j=0; j<n; ++j)	{
				if ((i & (1 << j)) != 0)	{
					if (ans < dp[i][j])	ans = dp[i][j];
				}
			}
		}
	}
	printf ("%I64d
", ans);

    return 0;
}

  

编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4832592.html