CodeForces 28D Don't fear, DravDe is kind dp

题目链接:点击打开链接

要使得删除后车队是合法的,即对于车队中的每辆车, l+r+c 都相同,则按l+r+c分类。

然后dp一下。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <set>
#include <vector>
#include <map>
using namespace std;
#define ll int
#define N 100005
struct node{
	int v,c,l,r;
	int num;
}car[N];
ll n;
vector<int>G[N], tmp;
set<int> myset;
set<int> ::iterator p;
map<int,int> mymap;
map<int,int> per;
map<int,int> sig;
int pos[N], endpos;
ll work(ll x){
	if(G[x].size()==0)return 0;
	mymap.clear();
	per.clear();
	sig.clear();
	mymap[0] = 0;
	per[0] = -1;
	sig[0] = -1;
	int ans = 0;
	endpos = -1;
/*	cout<<"---x:"<<x<<endl;
	for(int i = 0; i < G[x].size(); i++)cout<<G[x][i]<<" ";
	puts("---");/**/
	for(int i = 0; i < G[x].size(); i++) {
		node now = car[G[x][i]];
		if(mymap.find(now.l)==mymap.end())
			continue;
	//	cout<<"now: "<<G[x][i]<<endl;
		if(mymap.find(now.l+now.c)==mymap.end() || mymap[now.l+now.c]<mymap[now.l]+now.v) {
			mymap[now.l+now.c] = mymap[now.l]+now.v;
			sig[now.l+now.c] = G[x][i];
			per[G[x][i]] = sig[now.l];
		}
		if(now.r==0 && ans<mymap[now.l+now.c])ans = mymap[now.l+now.c], endpos = G[x][i];
	}
	return ans;
}
int main(){
	ll i,j,u,v;
	while(cin>>n){
		for(i = 1; i <= n; i++) G[i].clear();
		myset.clear();
		mymap.clear();
		for(i = 1; i <= n; i++)
			scanf("%d%d%d%d",&car[i].v,&car[i].c,&car[i].l,&car[i].r), car[i].num = i;
		for(i = 1; i <= n; i++) {
			myset.insert(car[i].c+car[i].l+car[i].r);
		}
		i = 1;
		for(p = myset.begin(); p!=myset.end(); p++, i++)
			mymap[*p] = i, pos[i] = *p;
		for(i = 1; i <= n; i++)
			G[mymap[car[i].c+car[i].l+car[i].r]].push_back(i);
		int ans = 0;
		for(i = 1; i <= n; i++) {
			int now = work(i);
			if(now>ans) {
				ans = now;
				tmp.clear();
				u = endpos;
				while(u!=-1) {
					tmp.push_back(u);
					u = per[u];
				}
			}
		}
		cout<<tmp.size()<<endl;
		for(i = tmp.size()-1; i>=0; i--)
			printf("%d%c",tmp[i],i?' ':'\n');
	}
	return 0;
}

CodeForces 28D Don't fear, DravDe is kind dp,布布扣,bubuko.com

CodeForces 28D Don't fear, DravDe is kind dp

时间: 2024-10-11 01:35:15

CodeForces 28D Don't fear, DravDe is kind dp的相关文章

Codeforces28D Don&#39;t fear, DravDe is kind DP

题目传送门:http://codeforces.com/problemset/problem/28/D 题意:给你$N$个物品,每个物品有其价格$P_i$,之前必须要买的物品价格和$L_i$,之后必须要买的物品价格和$R_i$和价值$W_i$.试给出一种物品的选择方案,使得满足所有选择的物品的条件且选择物品的价值和最大(物品的选择顺序必须要与原来的顺序相同).$N \leq 10^5 , P , L , R \leq 10^5 , W \leq 10^4$ 很像背包DP,所以就是背包DP(雾 我

Codeforces Round #260 (Div. 1) A. Boredom (DP)

题目链接:http://codeforces.com/problemset/problem/455/A A. Boredom time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Alex doesn't like boredom. That's why whenever he gets bored, he comes up with

codeforces 289B - Polo the Penguin and Matrix 二分+dp

题意:给你一个序列,每一次可以对序列里面任意数+d 或者 -d 问你最少多少步能够使得数列里面所有的数相等 解题思路:从 1 - 10000 枚举这个数,二分找数列中小于等于它的最大的那个数,然后求前缀和以后刻意快速求出差值和的绝对值,差值和/d 就是我们所求数. 解题代码: 1 // File Name: 289b.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月29日 星期二 22时33分11秒 4 5 #include<vecto

Codeforces 75D Big Maximum Sum 最大子段和 dp

题目链接:点击打开链接 题意: 第一行 n m n个vector 下面n行 第一个数字u表示vector 的大小,然后后面u个数字给出这个vector 最后一行m个数字 表示把上面的vector拼接起来 得到一个大序列,求这个大序列的最大子段和 先预处理出每个vector的最大子段和,左起连续最大,右起连续最大,所有数的和 然后dp 一下.. #include <cstdio> #include <iostream> #include <algorithm> #incl

Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题

除非特别忙,我接下来会尽可能翻译我做的每道CF题的题面! Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题 题面 胡小兔和司公子都认为对方是垃圾. 为了决出谁才是垃圾,大哥拿来了一袋老鼠,其中有w只白老鼠和b只黑老鼠.胡小兔先抓,先抓到白老鼠的人赢. 每次学姐抓完老鼠之后,总会有另外一只老鼠从袋子里自己跑出来(这只老鼠不算任何人抓的),而胡小兔抓老鼠时则不会发生这样的事. 每次袋子里的每只老鼠被抓到的概率相等,当有一只老鼠跑出来的时候,每只老鼠跑出来的几率也相

# codeforces 1272 F. Two Bracket Sequences(三维dp + bfs)

codeforces 1272 F. Two Bracket Sequences(三维dp + bfs) 题目大意 输入两个括号序列 s,t(不一定合法),你需要构造一个尽可能短的合法括号序列使得s,t 都是这个序列的子序列(子序列意味着不用连续) 解题思路 dp[i][j][k]表示匹配到s的第i个字符,匹配到t的第j个字符,并且此时(的个数比)多k个的时候的最小合法序列长度,k的上限是200(s和t中最多200个(或者)). 状态转移: 枚举答案合法序列的每一位是放置(或者) ? 放置(,如

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #362 (Div. 1) B. Puzzles 树形dp,概率

题目链接: http://codeforces.com/problemset/problem/696/B 题意: 一个树,dfs遍历子树的顺序是随机的.所对应的子树的dfs序也会不同.输出每个节点的dfs序的期望 思路: http://www.cnblogs.com/01world/p/5795498.html 假设四个子节点为A,B,C,D,因为排列等可能,所以A在B前面的概率跟A在B后面的概率相等,C和D对于A而言一样.所以遍历A的时间期望就是( t(B) + t(C) + t(D) )/2

codeforces 161 D. Distance in Tree(树形dp)

题目链接:http://codeforces.com/problemset/problem/161/D 题意:给出一个树,问树上点到点的距离为k的一共有几个. 一道简单的树形dp,算是一个基础题. 设dp[i][len]表示i为根距离为len的一共有几个点. 一般的树形dp都是先dfs然后再更新dp的值,注意按这样写就行了.而且一般的树形dp都是设dp[i][k]i为根,k为条件. void dfs(int u , int pre) { int len = vc[u].size(); dp[u]