POJ3544 Journey with Pigs 动规基础贪心思想

非常经典的贪心题目,没有严格证明的话,肯定是YY着做的,题意:

约翰要从A到B,途中会经过N个村庄,他会带N只猪,然后卖掉,每个村庄卖一只,第i个村庄的人出价pi 每斤,从A到第i个存在的距离为disi,而且运一只猪需要话花费t * disi每斤,t一开始会给定

输入第一行n,t

接下来第一行 n个数,代表各个猪的重量

在接下来第二行n个数,代表每个村庄距离A的距离dis

在接下来第三行n个数,代表每个村庄出价p

输出n个数,表示每个村庄买的哪只猪

这题目一开始看到就往dp方向去想,但是发现不行,于是大胆的YY了一把,直接按照  p - t * dis  从小到大来排序,然后猪的重量也从小到大排序,同时记录他们的编号,最后重新用一个哈希来记录即可,弄完举了几个案例发现没什么问题,就交了结果WA了,觉得自己不太对

于是就去好好的写了一下,肯定是跟 p - t * dis有关系,所以把这两列数进行了乘法运算,怎么乘岁自己,倒着,正着,然后什么都不是的,最后发现是正着的值比较高,那么我YY的就没有错,最后再仔细看题目,发现题意没理解错啊,最后看一下数据范围,发现t<=1000 000 000,这样一乘就超了32位,所以改了一下longlong,然后就过了

不错的贪心题目,多做做贪心为dp做铺垫,留着自己以后回顾看看挺不错的

#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>
#include<queue>

#define ll long long
#define LL __int64
#define eps 1e-8

//const ll INF=9999999999999;

#define inf 0xfffffff

using namespace std;

//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;

const int N = 1000 + 5;

ll n;
ll t;

typedef struct W{
	ll w;
	ll id;
};

W q[N];

typedef struct Node {
	ll dis,p;
	ll cha;//价格与距离差值
	ll id;
};

Node node[N];

void clear() {
	memset(node,0,sizeof(node));
	memset(q,0,sizeof(q));
}

bool cmp (Node x,Node y) {
	return x.cha < y.cha;
}

bool cmp1 (W x,W y) {
	return x.w < y.w;
}

int main() {
	while(scanf("%lld %lld",&n,&t) == 2) {
		ll hash[N];
		for(int i=0;i<n;i++) {
			scanf("%lld",&q[i].w);
			q[i].id = i;
		}
		for(int i=0;i<n;i++)
			scanf("%lld",&node[i].dis);
		for(int i=0;i<n;i++)
			scanf("%lld",&node[i].p);
		for(int i=0;i<n;i++) {
			node[i].cha = node[i].p - node[i].dis * t;
			node[i].id = i;
		}
		sort(node,node+n,cmp);
		sort(q,q+n,cmp1);
		for(int i=0;i<n;i++)
			hash[node[i].id] = q[i].id;
		for(int i=0;i<n - 1;i++)
			printf("%lld ",hash[i] + 1);
		printf("%lld\n",hash[n - 1] + 1);
	}
	return 0;
}

POJ3544 Journey with Pigs 动规基础贪心思想

时间: 2024-10-12 16:17:43

POJ3544 Journey with Pigs 动规基础贪心思想的相关文章

0-1背包问题(动规基础,好吧虽然我现在在说大话,待续...)

(此位老兄的讲解深得我意,特来推荐:http://blog.csdn.net/insistgogo/article/details/8579597) 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. POINT: 1·每种物品仅有一件,可以选择放或不放. 2·子问题---将前i件物品放入容量为V的背包中.价值总和为f[i][V]; 若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵

动规基础——01背包问题(背包问题Ⅱ)

题目来源:领扣 | LintCode 有 i 个物品和一个总容量为 j 的背包. 给定数组 weight 表示每个物品的重量和数组 value 表示每个物品的价值,求最大价值.(物品不能分割) 背包问题II 这道题是一道动态规划(dp)算法的基础题,有两种实现方式,分别是递归和递推(迭代),前者比后者好理解. 解题思路 首先,题目的要求是找出最大价值,所以我们要想,怎么存放才能让他的价值最大呢?因为物品具有重量,背包容量也有限,所以我们不能每次都放入最大价值的物品,举个例子,假设背包容量为 10

动规讲解基础讲解一——01背包(模板)

作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的: 有n件物品,第i件物品(I = 1,2,3…n)的价值是vi, 重量是wi,我们有一个能承重为m的背包,我们选择一些物品放入背包,显然放入背包的总重量不超过m.我们要求选择物品的总价值最大,请问如何选择?这里我们假设所有出现的数都是正整数. 第一想法是? (1) 枚举?万能的枚举啊.但对于n件物品,每件都可以选择取或者不取,总的可能性有2n, n = 30就大约已经有10亿种可能了!枚举所

【线性动规】最大子段和

题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入输出格式 输入格式: 输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度. 第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列. 输出格式: 输入文件maxsum1.out仅包括1个整数,为最大的子段和是多少.子段的最小长度为1. 输入输出样例 输入样例#1: 7 2 -4 3 -1 2 -4 3 输出样例#1: 4 说明 [样例说明]2 -4 3 -1 2 -4 3 [数据规模与约定] 对于

【BZOJ3875】【Ahoi2014】骑士游戏 SPFA处理有后效性动规

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44040735"); } 题解: 首先一个点可以分裂成多个新点,这样就有了图上动规的基础. 即f[i]表示i点被消灭的最小代价,它可以由分裂出的点们更新. 但是这个东西有后效性,所以我们用SPFA来处理它. spfa处理后效性动规 我

HDU 1069 Monkey and Banana (动规)

Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7248    Accepted Submission(s): 3730 Problem Description A group of researchers are designing an experiment to test the IQ of a

POJ 2955 Brackets (动规)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2999   Accepted: 1536 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

sicily 1091 Maximum Sum (动规)

1 //1091.Maximum Sum 2 //b(i,j) = max{b(i,j-1)+a[j], max(b(i-1,t)+a[j])} (t<j) 3 #include <iostream> 4 using namespace std; 5 6 int main() { 7 int t; 8 cin>>t; 9 while (t--) { 10 int n; 11 cin>>n; 12 int a[n+1]; 13 for (int i = 1; i &

ACM/ICPC 之 经典动规(POJ1088-滑雪)

POJ1088-滑雪 将每个滑雪点都看作起点,从最低点开始逐个由四周递推出到达此点的最长路径的长度,由该点记下. 理论上,也可以将每一点都看作终点,由最高点开始计数,有兴趣可以试试. 1 //经典DP-由高向低海拔滑雪-求最长路 2 //Memory:372K Time:32 Ms 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 using