贪心问题
区间找点
喷水装置(一)
喷水装置(二)
Rader
buying feed
同样是先输入组数
然后输入要买K磅,从0点出发终点为e,n家商店
n行输入,这些商店的坐标,最多能买进多少磅种子,每磅Ci元
在每个商店买一磅并到达终点的花费作为单价(c[i]+(E-x[i])),不用考虑距离只用贪心选单价小的即可
2 5 3
3 1 2 单价为(5-3)+2=4
4 1 2 (5-4)+2=3
1 1 1 (5-1)+1=5
输出 7
至于DP加单调队列优化 ,
滑雪
---------------------
color the fence
田忌赛马
寻找最大数
过河问题
独木舟上的旅行
Strategic Game
3 域的说明: 用yes,no分别表示某节点上放置士兵与否守住整棵子树的最小需求量; 用flag标记某节点的no值是否有效,即在该点不放置士兵时no值是否可以取道,一个节点的flag只是标记no的,与yes无关,且由其子节点决定,如果该节点的no取的子节点的值中有一个yes,即有一个子节点上放置有士兵,则flag=1; 守住所有的边(本题要求): 状态转移方程: dp[father].yes= (min (dp[child].yes, dp[child].no) 之和); 在某节点上放置士兵,则该节点的子节点是否放置士兵都无所谓,取更小者即可; dp[father].no= dp[child].yes 之和; 不在某节点上放置士兵,则该节点的子节点必须放置士兵; 守住所有的点(不是这一题,自己推的,也不知道是否正确,以后应该用得到): 状态转移方程: dp[father].yes= ( min(dp[child].yes,dp[child].no) 之和); 在某节点上放置士兵,则该节点的子节点是否放置士兵都无所谓,取更小者即可; if(dp[child].yes<=dp[child].no) dp[father].no+= dp[child].yes, dp[father].flag=1; 如果一个子节点上放置士兵时的最优解比不放时的还优,那么自然取放置士兵,同时因有一个子节点放置了士兵,则父节点就可以不放,标记flag=1; else{ if(t[child].flag) t[x].no+= t[child].no; //某个子节点允许不放士兵,父节点依旧加,只是不标记而已,因为父节点可以通过其他的子节点上放置士兵来守住该父节点; else t[x].no+= t[child].yes, t[x].flag=1;//某子节点不允许不放士兵,则必须放一个,同时因为放了,父节点可以不放,标记flag=1; } 其中树的构造,我是开struct的,和之前的一样(见我的pku3342里面有关于构造树的详细说明),其实也可以用vector的; 其实这题的另一做法是二分图,用到里面的一个结论,什么点最大覆盖的,可以百度,但树形DP的代码是运行最快的,二分图很慢;
4
/*2011-03-02 15:47:07 Accepted 1054 140MS 312K 1313 B C++*/ #include<stdio.h> #include<string.h> #include<iostream> using namespace std; struct Node{
int father,brother,child; int yes,no; void init(){
father=brother=child=0; yes=1,no=0; } }t[1505]; void DFS(int x){ int child=t[x].child; while(child){ DFS(child);
t[x].yes+= min(t[child].yes,t[child].no); t[x].no+= t[child].yes; child= t[child].brother; } } int main() {
int n,i,j,cnt,root; bool use[1505];
while(scanf("%d",&n)!=EOF) {
memset(use,0,sizeof(use)); int Root; for(i=1;i<=n;i++){
5
scanf("%d:(%d)",&root,&cnt), root++; if(i==1) Root=root; if(!use[root]){ t[root].init(); use[root]=1; } while(cnt--){
scanf("%d",&j), j++; if(!use[j]){ t[j].init(); use[j]=1; }
t[j].brother=t[root].child; t[j].father= root; t[root].child= j; } }
DFS(Root);
printf("%d\n",min(t[Root].yes,t[Root].no)); } }
农民木板
#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int a[20010];
int cmp(const void *e,const void *f)
{
return (*(int *)e-*(int *)f);
}
int main()
{
int i,j,n,m,t;
__int64 sum,s;
scanf("%d",&n);
for(i=0;i<=n-1;i++)
{
scanf("%d",&a[i]);
}
qsort(a,n,sizeof(a[0]),cmp);
sum=0;
for(i=1;i<=n-1;i++)
{
s=(a[i-1]+a[i]);
sum+=s;
for(j=i+1;j<=n-1;j++)
{
if(a[j]<s)
{
a[j-1]=a[j];
}else
{
break;
}
}
a[j-1]=s;
}
printf("%I64d/n",sum);
return 0;
}
线段树
市长的海报
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
using namespace std;
const int maxn = 100005;
const int INF = 1000000000;
struct node
{
int l, r, color;
} tree[4 * maxn];
int n;
int hash[10000005], a[10005], b[10005];
bool vis[10005];
void build(int l, int r, int rt)
{
tree[rt].l = l;
tree[rt].r = r;
tree[rt].color = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(l, mid, L(rt));
build(mid + 1, r, R(rt));
}
void update(int l, int r, int rt, int val)
{
if(tree[rt].l == l && tree[rt].r == r)
{
tree[rt].color = val;
return;
}
if(tree[rt].color == val) return;
if(tree[rt].color)
{
tree[L(rt)].color = tree[R(rt)].color = tree[rt].color;
tree[rt].color = 0;
}
int mid = (tree[rt].l + tree[rt].r) >> 1;
if(r <= mid) update(l, r, L(rt), val);
else if(l > mid) update(l, r, R(rt), val);
else
{
update(l, mid, L(rt), val);
update(mid + 1, r, R(rt), val);
}
}
void query(int l, int r, int rt)
{
if(tree[rt].color)
{
vis[tree[rt].color] = true;
return;
}
if(r <= tree[L(rt)].r) query(l, r, L(rt));
else if(l >= tree[R(rt)].l) query(l, r, R(rt));
else query(l, tree[L(rt)].r, L(rt)), query(tree[R(rt)].l, r, R(rt));
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
build(1, maxn, 1);
memset(hash, 0, sizeof(hash));
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &a[i], &b[i]);
hash[a[i]] = hash[b[i]] = 1;
}
int cnt = 0;
for(int i = 1; i <= 10000000; i++)
if(hash[i]) hash[i] = ++cnt;
for(int i = 1; i <= n; i++)
update(hash[a[i]], hash[b[i]], 1, i);
memset(vis, false, sizeof(vis));
query(1, cnt, 1);
int ans = 0;
for(int i = 1; i <= n; i++)
if(vis[i]) ans++;
printf("%d\n", ans);
}
return 0;
}
#include<stdio.h>
#define Lson(n) (n<<1)
#define Rson(n) (n<<1|1)
#define MID(a,b) (a+b>>1)
const int MAXN=200005;
int N,P[MAXN],V[MAXN],Loc,Ans[MAXN],SegmTree[MAXN<<2];
void Build(int L,int R,int N)
{
SegmTree[N]=R-L+1;
if(L!=R)
{
int M=MID(L,R);
Build(L,M,Lson(N));
Build(M+1,R,Rson(N));
}
}
void Insert(int Pos,int L,int R,int N)
{
--SegmTree[N];
if(L==R)
{
Loc=L;
}
else
{
int M=MID(L,R);
if(SegmTree[Lson(N)]>Pos) Insert(Pos,L,M,Lson(N));
else Insert(Pos-SegmTree[Lson(N)],M+1,R,Rson(N));
}
}
int main()
{
while(scanf("%d",&N)==1)
{
Build(0,N-1,1);
for(int i=0;i<N;++i)
{
scanf("%d%d",&P[i],&V[i]);
}
for(int i=N-1;i>=0;--i)
{
Insert(P[i],0,N-1,1);
Ans[Loc]=V[i];
}
for(int i=0;i<N;++i)
{
printf("%d%c",Ans[i],i+1<N?' ':'\n');
}
}
}