寒假训练25号

E - 5 HDU - 1078
dfs

#include <iostream>
#include <algorithm>
using namespace std;

int n, k;
int p[101][101];
int dp[101][101];
int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };
void dfs(int x,int y)
{
	for (int i = 0; i < 4; ++i)  //四个方向
	{
		for (int t = 1; t <= k; ++t)  //走1--k步
		{
			int tx = x + t * dx[i];  //temp坐标 
			int ty = y + t * dy[i];
			if (tx >= 0 && ty >= 0 && tx < n && ty < n)
			{
				if (p[tx][ty] > p[x][y])
				{
					if (dp[tx][ty] == 0)
					{
						dfs(tx, ty);
						dp[x][y] = max(dp[x][y], dp[tx][ty] + p[x][y]);
					}
					else
					{
						dp[x][y] = max(dp[x][y], dp[tx][ty] + p[x][y]);
					}
				}
			}
		}
	}
	if (dp[x][y] == 0) dp[x][y] = p[x][y];
	return;
}

int main()
{
	while (cin >> n >> k)
	{
		if (n == -1&&k==-1) break;
		for (int i = 0; i < n; ++i)
		{
			for (int t = 0; t < n; ++t)
				cin >> p[i][t];
		}
		memset(dp, 0, sizeof(dp));
		dfs(0, 0);
		cout << dp[0][0] << endl;
	}
}

F - 6 HDU - 1072
定时走迷宫+时间重置
思路:dfs+剪枝(也可用bfs做)

#include <iostream>
#include <cstring>
using namespace std;

int n, m;

int time[8][8],step[8][8];
int tim, st;
int minstep;
const int inf = 9999;
int map[8][8];
int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };

void dfs(int sx, int sy,int tim,int st)
{
	if (sx<0 || sx>=n || sy<0 || sy>=m) return;  
	if (st >= minstep || tim <= 0) return;
	if (map[sx][sy] == 0) return;
	if (map[sx][sy] == 3)  //到达目标
	{
		if (st < minstep) minstep = st;
		return;
	}
	if (map[sx][sy] == 4) tim = 6;
	if (st >= step[sx][sy] && time[sx][sy] >= tim) return; //剪枝 

	step[sx][sy] = st ;
	time[sx][sy] = tim ;
	for (int i = 0; i < 4; ++i)
	{
		int tx = sx + dx[i];
		int ty = sy + dy[i];
		dfs(tx, ty,tim-1,st+1);
	}

}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		cin >> n >> m;
		int sx, sy, ex, ey;
		for (int i = 0; i < n; ++i)
		{
			for (int t = 0; t < m; ++t)
			{
				cin >> map[i][t];
				if (map[i][t] == 2)
				{
					sx = i; sy = t;
				}
				if (map[i][t] == 3)
				{
					ex = i; ey = t;
				}
			}
		}
		memset(step, inf, sizeof(step));  //初始化为inf,不是0
		memset(time, 0, sizeof(time));
		time[sx][sy] = 6;
		tim = 6; st = 0; minstep = inf;
		dfs(sx, sy,6,0);
		if (minstep == inf) cout << -1 << endl;
		else cout << minstep << endl;
	//	cout << step[ex][ey] << endl;
	}
}

H - 8 UVA - 11389
贪心问题
方法:先对早、晚班车时长排序(一个升序,一个降序,之后对应项相加与d比较,计算出超时总量即可)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

void upsort(int a[], int n)  //升序
{
	for (int i = 0; i < n - 1; ++i)
	{
		for (int t = i + 1; t < n; ++t)
		{
			if (a[i] > a[t])
			{
				int x = a[i];
				a[i] = a[t];
				a[t] = x;
			}
		}
	}
}

void downsort(int a[], int n)  //降序
{
	for (int i = 0; i < n - 1; ++i)
	{
		for (int t = i + 1; t < n; ++t)
		{
			if (a[i] < a[t])
			{
				int x = a[i];
				a[i] = a[t];
				a[t] = x;
			}
		}
	}
}

int main()
{
	int n, d, r;
	int mo[105], en[105];
	while (cin >> n >> d >> r)
	{
		if (n ==0 &&d ==0&& r == 0) break;
		memset(mo, n, 0);
		memset(en, n, 0);
		for (int i = 0; i < n; ++i)
		{
			cin >> mo[i];
		}
		upsort(mo, n);
		for (int i = 0; i < n; ++i)
		{
			cin >> en[i];
		}
		downsort(en, n);
		int s = 0;
		for (int i = 0; i < n; ++i)
		{
			int f = mo[i] + en[i];
			if (f > d)
			{
				s = s + f - d;
			}
		}
		cout << s * r << endl;
	}
}

I - 9 HDU - 1754
//线段树 - 老师询问 - 套模板(24号HDU - 1166线段树:把sum改为记录最大值)

#include <iostream>
using namespace std;
//HDU - 1166线段树模板修改 
const int maxn = 200001;
int n,m;  //n个数,m条命令
int p[maxn];
int s;
struct node
{
	int l;
	int r;
	int max;//储存最大值
}t[maxn << 2];

void build(int l, int r, int idx)  //l:左边界,r:右边界,idx:下标
{
	t[idx].l = l;
	t[idx].r = r;
	if (l == r)
	{
		t[idx].max = p[l];
		return;
	}
	else
	{
		int mid = (t[idx].l + t[idx].r) >> 1;
		build(l, mid, (idx << 1) + 1);  //左子树;重点理解下标idx的变化
		build(mid + 1, r, (idx << 1) + 2);  //右子树
		t[idx].max =( t[(idx << 1) | 1].max > t[(idx << 1) + 2].max ? t[(idx << 1) | 1].max : t[(idx << 1) + 2].max);  //父节点存储左右子树大的数值
	}
}

int query(int l, int r, int idx)  //查询
{
	if (l <= t[idx].l&&r >= t[idx].r)
	{
		//	cout << "s=s+t[idx].sum=" << s << '+' << t[idx].sum<<endl;
		if(t[idx].max>s) s = t[idx].max;  //注意这个if条件,否则递归过程s会被还原
		if (l == t[idx].l&&r == t[idx].r)
		{
			if (t[idx].max > s) s = t[idx].max;
			return s;
		}
	}
	
	else
	{
		int mid = (t[idx].l + t[idx].r) >> 1;
		if (r <= mid)
		{
			int x=query(l, r, (idx << 1) | 1);
			if (x > s) s = x;
		}
		else if (l > mid)
		{
			int x=query(l, r, (idx << 1) + 2);
			if (x > s) s = x;
		}
		else
		{
			int x=query(l, mid, (idx << 1) | 1);  //询问左子树
			if (x > s) s = x;
			int y=query(mid + 1, r, (idx << 1) + 2);  //询问右子树
			if (y > s) s = y;
		}
	}
}

void update(int i, int idx, int val)//
{
	p[i] = val;
	if(val>t[idx].max) t[idx].max = val;  //修改sum
	if (t[idx].l == i && i == t[idx].r)	return;
	else
	{
		int mid = (t[idx].l + t[idx].r) >> 1;
		if (i <= mid) update(i, (idx << 1) | 1, val);
		else update(i, (idx << 1) + 2, val);
	}
}


int main()
{
	while (cin >> n >> m)
	{
		for (int i = 1; i <= n; ++i)
		{
			cin >> p[i];
		}
		build(1, n, 0);
		/*	for (int i = 0; i < 30; ++i)
			{
				cout << t[i].sum << ' ';
			}cout << endl;*/
		char op;
		while (m--)
		{
			cin >> op;
			int a, b;
			cin >> a >> b;
			if (op == 'Q')
			{
				s = 0;
				query(a, b, 0);
				printf("%d\n", s);
				//		cout << s << endl;
			}
			else if (op == 'U')
			{
				update(a, 0, b);
			}

			/*	for (int i = 0; i < 30; ++i)
				{
					cout << t[i].sum << ' ';
				}cout << endl<<endl;*/
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅若清风cyf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值