【算法随笔】贪心练习

目录

一、货舱地址

二、最大子段和

三、纪念品分组

四、排座椅

五、矩阵消除游戏


一、货舱地址

P10452 货仓选址 - 洛谷

代码如下:

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 1e5+10; 
int a[N];

int main()
{
	int n; cin >> n;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i]; 
	}
	sort(a+1,a+n+1);
	int ret = 0;
//	for(int i = 1; i <= n; i++)
//	{
//		ret += abs(a[i] - a[(n+1)/2]);
//	}
    for(int i = 1; i <= n/2; i++)
    {
    	ret += abs(a[i] - a[n+1-i]);
	}
	cout << ret << endl;
	return 0;
}

二、最大子段和

P1115 最大子段和 - 洛谷

代码如下:

cpp 复制代码
#include<iostream>
using namespace std;

const int N = 2e5 + 10;
int f[N];

int main()
{
	int n; cin >> n;
	int ret = -1e9;
	for(int i = 1; i <= n; i++)
	{
		int e; cin >> e;
		f[i] = max(f[i-1] + e, e);
		ret = max(ret,f[i]);
	}
	cout << ret << endl;
	return 0;
 }

三、纪念品分组

P1094 NOIP 2007 普及组 纪念品分组 - 洛谷

代码如下:

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 3e4 + 10;
int a[N];

int main()
{
	int w,n;
	cin >> w >> n;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	sort(a+1,a+n+1);
	int l = 1, r = n;
	int ret = 0;
	while(l <= r)
	{
		if(a[l] + a[r] <= w)
		{
			l++;
		} 
		r--;
		ret++;
	}
	cout << ret << endl;
	return 0;
}

四、排座椅

P1056 NOIP 2008 普及组 排座椅 - 洛谷

代码如下:

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 1010;

struct Node
{
	int index;
	int cnt;
}row[N],col[N];

//按拆分数量从大到小排列 
bool cmp1(Node& x,Node& y)
{
	return x.cnt > y.cnt;
}
//按行列数从小到大排列输出 
bool cmp2(Node& x, Node& y)
{
	return x.index < y.index;
}

int main()
{
	int m,n,k,l,d;
	cin >> m >> n >> k >> l >> d;
	for(int i = 1; i <= m; ++i)
	{
		row[i].index = i;
	}
	for(int i = 1; i <= n; ++i)
	{
		col[i].index = i;
	}
	while(d--)
	{
		int x,y,p,q;
		cin >> x >> y >> p >> q;
		if(x == p)
		{
			col[min(y,q)].cnt++;
		}
		else{
			row[min(x,p)].cnt++;
		}
	}
	
	// 从大到小排 
	sort(row+1,row+1+m,cmp1);
	sort(col+1,col+1+n,cmp1);
	
	//从小到大排 
	sort(row+1,row+1+k,cmp2);
	sort(col+1,col+1+l,cmp2);
	
	for(int i = 1; i <= k; ++i)
	{
		cout << row[i].index << " ";
	}
	cout << endl;
	for(int i = 1; i <= l; ++i)
	{
		cout << col[i].index << " ";
	}
	cout << endl;
	return 0;
}

五、矩阵消除游戏

矩阵消除游戏

代码如下:

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 20;

int n, m, k;
int a[N][N];
int col[N]; // 统计列和
// 统计 x 的⼆进制表⽰中 1 的个数
int calc(int x)
{
int ret = 0;
while(x)
{
ret++;
x -= x & -x;
}
return ret;
}
// 按照值从⼤到⼩排序
bool cmp(int a, int b)
{
return a > b;
}
int main()
{
cin >> n >> m >> k;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
cin >> a[i][j];
int ret = 0;
// 暴⼒枚举出⾏的所有选法
for(int st = 0; st < (1 << n); st++)
{
int cnt = calc(st);
if(cnt > k) continue; // 不合法的状态
memset(col, 0, sizeof col);
int sum = 0; // 记录当前选法中的和
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if((st >> i) & 1) sum += a[i][j];
else col[j] += a[i][j];
}
}

// 处理列
sort(col, col + m, cmp);
// 选 k - cnt 列
for(int i = 0; i < k - cnt; i++) sum += col[i];
ret = max(ret, sum);
}
cout << ret << endl;
return 0;
}