POJ 1769(Minimizing maximizer) 线段树优化的dp
作者:互联网
题意:是有一个装置可以输出n个数的最大值, 这个装置由m个排序器组成, 每个排序器可以将这n个数从s 到 t的数按照从小到大的顺序排列, 有一个人发现将m个排序器中的一些排序器去掉仍然不影响功能, 现在问你最少需要多少个排序器可以完成功能。
思路:dp[i][j]表示更新到第i个区间,到第j个位置最小要几个区间。// 对线段树还是不太熟悉
T代码:
#include <queue> #include<iostream> #include<stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <ctime> #include <queue> using namespace std; int dp[55000]; int main(){ int i,j,k,f1,f2,f3,f4,t1,t2,t3,t4,n,m; // freopen("in.txt","r",stdin); cin >> n>> m; for(i=0;i<=n;i++) dp[i]=1e9+7; dp[1]=0; //移动到1的费用为0 for(i=1;i<=m;i++){ scanf("%d %d",&t1,&t2); for(j=t1;j<=t2;j++){ if(j==t1){ f1=dp[j]; if(f1+1>=dp[t2])break; }else if(j>t1&&j<=t2){ dp[j]=min(dp[j],f1+1); } // cout << j <<"的费用为" << dp[j] << endl; } } cout << dp[n] << endl; return 0; }View Code
AC代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> // for memset #include <vector> // push_back() // vector<int>().swap(v); #include <set> //multiset set<int,greater<int>> //big->small #include <map> #include <stack> // top() #include <queue> // front() // priority_queue<T,vector<T>,greater<T> > #include <cmath> // auto &Name : STLName Name. #include <utility> #include <sstream> #include <string> // __builtin_popcount (ans); // 获取某个数二进制位1的个数 #include <cstdlib> // rand() #define IOS ios_base::sync_with_stdio(0); cin.tie(0) #define lowbit(x) (x&(-x)) using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int maxn = 5e5 + 5; struct T{ int l,r,m; }tree[maxn*4]; int ans,m,n,t1,t2; void build(int l,int r,int num) { tree[num].l=l; tree[num].r=r; if(l==r) { if(l==1)tree[num].m=0; else tree[num].m=INF; return; } int m=(l+r)/2; build(l,m,num*2); build(m+1,r,num*2+1); tree[num].m=min(tree[num*2].m,tree[num*2+1].m); } int query(int l,int r,int num) { if(tree[num].l>=l&&tree[num].r<=r) return tree[num].m; int mid=(tree[num].l+tree[num].r)/2; if(l>mid){ query(l,r,num*2+1); }else if(r<=mid){ query(l,r,num*2); }else if(r>mid&&l<=mid){ int v1=query(l,r,num*2); int v2=query(l,r,num*2+1); return min(v1,v2); } } void update(int num,int i,int c) { if(tree[num].l==tree[num].r&&tree[num].l==i) { tree[num].m=c; return; } int mid=(tree[num].l+tree[num].r)/2; if(i<=mid) update(2*num,i,c); else update(2*num+1,i,c); tree[num].m=min(tree[num*2].m,tree[num*2+1].m); } int main(void) { while(scanf("%d%d",&n,&m)!=EOF) { build(1,n,1); for(int i=1;i<=m;i++) { scanf("%d%d",&t1,&t2); int v1=query(t1,t2,1)+1; int v2=query(t2,t2,1); int v3=min(v1,v2); update(1,t2,v3); } printf("%d\n",query(n,n,1)); } return 0; }
标签:maximizer,排序,num,int,tree,Minimizing,POJ,include,dp 来源: https://www.cnblogs.com/jaszzz/p/12997109.html