zoukankan      html  css  js  c++  java
  • HDNOIP普及+提高整合

    好久没有更新博客了。。。这几天一直在切 HDNOIP。。。

    正式时跪惨了。。。所以考完后回来奋力切出了所有题。

    [COJ3351]HDNOIP201601回文质数

    试题描述

    回文数是具有对称性的自然数,例如 25352 和 1881 都是回文数。在一个完全由数字符 组成的字符串中任意取一个长度 L 的子字符串,都可以转化为一个不超过 L 位的整数,如果 此整数是质数,我们就把这个子串称为回文质数串。 
    你的任务是在一个完全由数字符组成的字符串 n 中找出第一个(位置最靠前的一个)长 度 L 的回文质数子串。

    输入

    先是 n,后是 L,中间用空格分开。 

    输出

    只有一项输出结果。如果 n 中存在符合条件的子串就输出这个子串,否则输出 n 中长度 L 的回文子串个数。 

    输入示例

    12301101113 3

    输出示例

    101

    数据规模及约定

    70%的数据满足 l<7。 
    100%的数据满足 0<l<=10;n 的位数不小于 l 且不大于 100。 

    题解

    暴力。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 110
    #define LL long long
    int n, k, ans;
    LL ten[12];
    char S[maxn];
    
    bool judge(LL x) {
    	int num[12], cnt = 0;
    	LL t = x;
    	while(x) {
    		num[++cnt] = x % 10;
    		x /= 10;
    	}
    	while(cnt < k) num[++cnt] = 0;
    	for(int i = 1; i <= cnt; i++) if(num[i] != num[cnt-i+1])
    		return 0;
    	ans++;
    	if(t == 1) return 0;
    	int m = (int)sqrt((double)t + .5);
    	for(int i = 2; i <= m; i++) if(t % i == 0)
    		return 0;
    	return 1;
    }
    
    int main() {
    	scanf("%s", S + 1); n = strlen(S + 1);
    	k = read();
    	
    	LL sum = 0;
    	ten[0] = 1;
    	for(int i = 1; i <= k; i++) ten[i] = ten[i-1] * 10;
    	for(int i = 1; i <= k; i++) sum = sum * 10 + S[i] - '0';
    	if(judge(sum)) return printf("%lld
    ", sum), 0;
    	for(int i = k + 1; i <= n; i++) {
    		sum = (sum - ten[k-1] * (S[i-k] - '0')) * 10 + S[i] - '0';
    		if(judge(sum)) return printf("%lld
    ", sum), 0;
    	}
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    

    [COJ3352]HDNOIP201602贪吃的宝宝

    试题描述

    宝宝每天要吃一包零食,借美食购物节的机会,他让妈妈领着买回来 n 包零食。食品的 包装上都标明了此食品的保质期,妈妈也还记得每包食品的价格。出于对宝宝健康的考虑, 妈妈规定宝宝每天吃零食不得超过一包且不准吃过期食品。 

    怎样安排宝宝吃零食的方案才能使浪费(无法吃上)的零食总价最少呢?你能帮宝宝找 到最小浪费总价吗?

    输入

    第一行是 n,接下来的 n 行每行两个整数,先是保质期,后是价格。保质期是从现在算 起的保质天数。 

    输出

    一个数,表示浪费食品的最小总价。 

    输入示例

    4
    2 4
    5 1
    1 3
    2 2

    输出示例

    2

    数据规模及约定

    60%的数据满足 n<10。 
    80%的数据满足 n<=1000,保质期不超 100000。 
    100%的数据满足 n<100000,且保质期<2^31,每包零食价格不超 2^15。 

    题解

    贪心。按照保质期从大到小排序,那么对于第 i 个食物,可以选择它前面的所有食物,可选择的个数为当前时刻与最大时刻(即第一个食物的保质期)之差,用个堆以价值为关键字存下所有食物,贪心地取即可。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 100010
    #define LL long long
    int n;
    struct Snack {
    	int d, v;
    	Snack() {}
    	Snack(int _, int __): d(_), v(__) {}
    	bool operator < (const Snack& t) const { return v < t.v; }
    } ss[maxn];
    bool cmp(Snack a, Snack b) { return a.d > b.d; }
    
    priority_queue <Snack> Q;
    int main() {
    	n = read();
    	for(int i = 1; i <= n; i++) {
    		int a = read(), b = read();
    		ss[i] = Snack(a, b);
    	}
    	
    	sort(ss + 1, ss + n + 1, cmp);
    	LL ans = 0, sum = 0;
    	for(int i = 1; i <= n; i++) {
    		if(i > 1 && ss[i].d != ss[i-1].d) {
    			int x = ss[i-1].d - ss[i].d;
    			while(!Q.empty() && x--) ans += Q.top().v, Q.pop();
    		}
    		Q.push(ss[i]); sum += ss[i].v;
    	}
    	int x = ss[n].d;
    	while(!Q.empty() && x--) ans += Q.top().v, Q.pop();
    	
    	printf("%lld
    ", sum - ans);
    	
    	return 0;
    }
    

    [COJ3353]HDNOIP201603紧急使命

    试题描述

    在久远以前的部落年代,s 部落因紧急事务要派人去往 t 部落。出于贪心,各部落分别 规定了对进入或路经本部落的人强制收费的额度,如果存在 s 到 t 的直达道路,使者只需缴 纳 t 部落的费用,否则还要向途经的各部落交“买路钱”。 部落编号从 1 到 n。题目数据除了 n、s、t 等信息外,还有 s 部落酋长给使者的钱数 k 以及各部落间的相邻关系信息。 

    相邻关系信息包括两个部落间直接互通道路的条数 m,还有每条道路所连两个部落的编 号及通过此道路所需的时间。 你的任务是由这些信息求出在钱数 k 的限制内,s 部落使者最少要花多少时间才能到达 t 部落?若没有 s 部落通向 t 部落的路径或每条能走的路径收费都超 k,就输出-1。 

    输入

    第一行依次是 n、m、k、s、t,共 5 个正整数。 
    第二行共有 n 个非负整数 ki,依次是 1、2……n 号部落的收费价格。 
    接下来的 m 行每行 3 个整数 a、b、c,表示 a 部落与 b 部落之间有一条不经过其他部落 的双向道路,需要花长度 c 的时间。 注意,a 部落与 b 部落间直接互通的道路可能不止一条。

    输出

    只有一项输出内容。 
    若在 k 的钱数内能从 s 到达 t,输出的是其中最快方案的时间数,否则输出-1,表示无 法到达 t。

    输入示例

    5 6 10 1 5
    7 2 3 8 4
    2 1 3
    1 4 2
    3 2 5
    4 5 1
    3 4 2
    5 3 7

    输出示例

    15

    数据规模及约定

    50%的数据满足 2<n<=10 且 k<100; 
    70%的数据满足 2<n<20 且 k<=100。 
    100%的数据满足 2<n<=100,0<k<10000,1<m<n^2,s≠t,0<s, t<=n。 
    每条道路满足:0<a,b<=n 且 0<c<=1000。 

    题解

    最短路。我拒绝写 SPFA。。。鬼知道有没有网格图。。。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 110
    #define maxm 20010
    #define maxk 10010
    #define oo 2147483647
    int n, m, k, s, t, val[maxn], head[maxn], next[maxm], to[maxm], dist[maxm];
    
    void AddEdge(int a, int b, int c) {
    	to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;
    	swap(a, b);
    	to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;
    	return ;
    }
    
    struct Node {
    	int x, y, d;
    	Node() {}
    	Node(int _1, int _2, int _3): x(_1), y(_2), d(_3) {}
    	bool operator < (const Node& t) const { return d > t.d; }
    } ;
    priority_queue <Node> Q;
    bool vis[maxn][maxk];
    int d[maxn][maxk];
    void Dijkstra() {
    	for(int i = 1; i <= n; i++)
    		for(int j = 0; j <= k; j++) d[i][j] = oo;
    	d[s][0] = 0;
    	Q.push(Node(s, 0, 0));
    	while(!Q.empty()) {
    		Node u = Q.top(); Q.pop();
    		if(vis[u.x][u.y]) continue;
    		vis[u.x][u.y] = 1;
    		for(int e = head[u.x]; e; e = next[e]) {
    			Node v(to[e], u.y + val[to[e]], 0);
    			if(u.y + val[to[e]] <= k && d[v.x][v.y] > d[u.x][u.y] + dist[e]) {
    				d[v.x][v.y] = d[u.x][u.y] + dist[e];
    				if(!vis[v.x][v.y]) Q.push(Node(v.x, v.y, d[v.x][v.y]));
    			}
    		}
    	}
    	return ;
    }
    
    int main() {
    	n = read(); int m = read(); k = read(); s = read(); t = read();
    	for(int i = 1; i <= n; i++) val[i] = read();
    	for(int i = 1; i <= m; i++) {
    		int a = read(), b = read(), c = read();
    		AddEdge(a, b, c);
    	}
    	
    	Dijkstra();
    	
    	int ans = oo;
    	for(int i = 0; i <= k; i++) ans = min(ans, d[t][i]);
    	
    	printf("%d
    ", ans < oo ? ans : -1);
    	
    	return 0;
    }
    

    [COJ3348]HDNOIP201604打电话

    试题描述

    小松鼠每天晚上都会给一位同学打电话,并且总要问一些类似的问题,结果有时候就会使得对方有些不耐烦。

    今天晚上,他又要开始打电话了,这次他有n种问题可问,其中第i种问题他最多会问ti次。他发现,同一种问题问了至少k次以后,对方就会对这问题不耐烦。他想知道,问了q问题之后,对方至少会对多少问题不耐烦。

    输入

    第一行三个整数n、k、q。第二行n个整数t1, t2, …, tn。

    输出

    一个数,对方至少会对多少种问题不耐烦。

    输入示例

    8 5 36
    6 9 10 2 8 4 1 7

    输出示例

    2

    数据规模及约定

    30%的数据中,n = 5,1 ≤ ti ≤ 30 
    100%的数据中,1 ≤ n,k ≤ 100000,1 ≤ ti ≤ 10000,1 ≤ q ≤ t1 + t2 + ⋯+ tn 

    题解

    还是贪心。先给所有的 t 减去 k-1 次,若不够则减到 0 为止,然后从大到小依次将所有的 t 减到 0;q 随之减小到 0 为止。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 100010
    int n, k, q, A[maxn], B[maxn], cnt;
    
    int main() {
    	n = read(); k = read(); q = read();
    	for(int i = 1; i <= n; i++) A[i] = read();
    	
    	sort(A + 1, A + n + 1);
    	for(int i = 1; i <= n; i++)
    		if(A[i] > k - 1) B[++cnt] = A[i] - k + 1, q -= k - 1;
    		else q -= A[i];
    	if(q <= 0) return puts("0"), 0;
    	for(int i = cnt; i; i--)
    		if(q > B[i]) q -= B[i];
    		else return printf("%d
    ", cnt - i + 1), 0;
    	
    	return 0;
    }
    

    [COJ3349]HDNOIP201605旅行路线

    试题描述

    落选UOI 地球代表队之后,小松鼠跑到了一个奇怪的地方玩耍。 
    这里有 n 个村庄和 n – 1 条道路,任何两个村庄之间都有唯一的简单路径相连通,小松鼠 每天晚上都会选择一个村庄住下,并且不会在同一个村庄住下两次。而每一个白天,他会沿着某两个村庄之间唯一的简单路径,从前一天晚上所在的村庄抵达另一个村庄,并在那里住 一个晚上。 
    小松鼠希望能把路上的风景看个够,所以需要一个在村庄住下的顺序,使得经过的总路 程最长。

    输入

    第一行一个整数 n。下面n − 1行,每行有三个整数 a、b、c 分别表示一条道路连接的两 个村庄各自的编号 a、b,和这条道路的长度 c。 

    输出

    一个数,最长的总路程。

    输入示例

    6
    2 1 3
    3 2 2
    4 5 2
    4 6 5
    2 4 4

    输出示例

    44

    数据规模及约定

    测试点 0~5,1 ≤ n ≤ 10 
    测试点 6~10,任何一个村庄最多与两条道路相连,1 ≤ n ≤ 100000,c = 1 
    测试点 11~13,任何一个村庄最多与两条道路相连,1 ≤ n ≤ 100000,1 ≤ c ≤ 100000 
    测试点 14~17,1 ≤ n ≤ 100000,c = 1 
    测试点 18~19,1 ≤ n ≤ 100000,1 ≤ c ≤ 100000 

    题解

    找出树的重心,以重心为根,处理出所有的 d[i] 表示节点 i(除重心外)到根节点的距离。若只有一个重心,则答案为 2∑d[i] - min{ d[i] };若有两个重心,则答案为 2∑d[i] - 两个重心之间的距离。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 100010
    #define maxm 200010
    #define oo 2147483647
    #define LL long long
    int n, m, head[maxn], next[maxm], to[maxm], dist[maxm];
    
    void AddEdge(int a, int b, int c) {
    	to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;
    	swap(a, b);
    	to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;
    	return ;
    }
    
    int root, size, f[maxn], siz[maxn], r2;
    bool fl;
    void getroot(int u, int fa) {
    	siz[u] = 1; f[u] = 0;
    	for(int e = head[u]; e; e = next[e]) if(to[e] != fa) {
    		getroot(to[e], u);
    		siz[u] += siz[to[e]];
    		f[u] = max(f[u], siz[to[e]]);
    	}
    	f[u] = max(f[u], size - siz[u]);
    	if(f[root] > f[u]) root = u, fl = 0;
    	else if(f[root] == f[u]) fl = 1, r2 = u;
    	return ;
    }
    
    LL dep[maxn], sum;
    void build(int u, int fa) {
    	sum += dep[u];
    	for(int e = head[u]; e; e = next[e]) if(to[e] != fa) {
    		dep[to[e]] = dep[u] + dist[e];
    		build(to[e], u);
    	}
    	return ;
    }
    
    int main() {
    	n = read();
    	for(int i = 1; i < n; i++) {
    		int a = read(), b = read(), c = read();
    		AddEdge(a, b, c);
    	}
    	
    	root = 0; f[0] = n + 1; size = n; getroot(1, 0);
    	build(root, 0);
    	sum <<= 1;
    	if(!fl) {
    		int mn = oo;
    		for(int e = head[root]; e; e = next[e]) mn = min(mn, dist[e]);
    		sum -= mn;
    	}
    	else
    		for(int e = head[root]; e; e = next[e]) if(to[e] == r2)
    			sum -= dist[e];
    	
    	printf("%lld
    ", sum);
    	
    	return 0;
    }
    

    大胆猜想,不用证明

    [COJ3350]HDNOIP201606弹飞松子

    试题描述

    小松鼠总喜欢让身边的所有物品都变得弹弹的。 
    他刚刚在地上沿直线摆放了 n 个弹簧,分别位于第 0、1、……、n – 1 个位置上。第 i 个位置上的弹簧有初始弹性di,表示落在这个弹簧上的物品将会被向后弹到第i + di个位置上。 小松鼠可以修改每个弹簧的弹性,每个弹簧有被修改的难度系数ai,表示如果将这个弹簧的 弹性修改为di′,需要消耗|di − di′| ∙ ai的代价,但弹簧是不能向前弹的。 这时,一个松子从天而降,恰好落在了第 0 个位置上。小松鼠知道,松子在第 i 个位置 上的弹簧上弹一下,他就能获得bi的收益。他希望松子最后能落在第 n 个位置上,并且获得 的总收益减去总代价最大。

    输入

    第一行一个整数 n。下面 n 行,每行三个整数di、ai、bi。 

    输出

    一个整数,最大的总收益减总代价的值

    输入示例

    9
    1 5 8
    2 5 8
    3 4 5
    5 2 6
    1 1 1
    4 3 7
    3 5 3
    4 4 9
    5 4 5

    输出示例

    23

    数据规模及约定

    30%的数据中,1 ≤ n ≤ 20 
    70%的数据中,1 ≤ n ≤ 1000 另有 20%的数据中,ai = 1 
    100%的数据中,1 ≤ n ≤ 60000,1 ≤ di ≤ n,1 ≤ ai ≤ 100,1 ≤ bi ≤ 5000 

    题解

    首先会想到斜率优化dp,于是推一波式子(令 Di = di + i)——

    我们发现无法 O(n) 维护凸壳,原因有:

    1.) aj 不单调

    2.) 需要分类讨论

    第 2 点很容易解决,我们可以分开处理,即分成两个坐标系,一个用来维护 i ≤ Dj 的情况,另一个维护 i ≥ Dj 的情况。

    第 1 点也不难解决,因为 a 的范围只有 100,这就意味着每个决策点的横坐标只有 100 种可能,于是我们可以分别维护 100 个横坐标当前能够取到的最优决策点,查询的时候分别在这 100 种横坐标中找就好了。

    当计算出 f(i) 时,当前决策点就产生了,我们向两个坐标系中分别插入这个决策点。其中,第一个坐标系中的每个决策点有一个“开始时间”属性,即当到达该时刻时即可使用这个决策点;第二个坐标系中每个决策点有一个“结束时间”属性,即到达这个时刻后就不能使用该决策点了(当前时刻时使用它的最后一时刻)。而以上所说的“开始、结束时间”就是 Di(想一想,为什么),前者可以用数组维护(设 F[x][t] 表示横坐标为 x,开始时间为 t 的最优决策点,即该点的 f(i)+Di·ai 最大),后者可以用堆维护(每个节点记录权值,即 f(i)-Di·ai 的值,以及结束时间,以权值为关键字建立堆)。

    时间复杂度 O(100n + nlogn)(想一想,为什么)

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cctype>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 60010
    #define maxa 110
    #define oo 1000000000
    int n, d[maxn], a[maxn], b[maxn], f[maxn];
    bool vP1[maxa][maxn];
    struct Node {
    	int val, pos;
    	Node() {}
    	Node(int _1, int _2): val(_1), pos(_2) {}
    } P1[maxa][maxn], mx1[maxa];
    struct Node2 {
    	int val, end, pos;
    	Node2() {}
    	Node2(int _1, int _2, int _3): val(_1), end(_2), pos(_3) {}
    	bool operator < (const Node2& t) const { return val < t.val; }
    } ;
    priority_queue <Node2> mx2[maxa];
    
    int main() {
    	n = read();
    	for(int i = 0; i < n; i++) {
    		d[i] = read() + i; a[i] = read(); b[i] = read();
    	}
    	
    	for(int i = 0; i <= 100; i++) mx1[i] = Node(-oo, 0);
    	f[0] = b[0];
    	P1[a[0]][d[0]] = Node(f[0] + d[0] * a[0], 0); vP1[a[0]][d[0]] = 1;
    	if(d[0] <= 0) mx1[a[0]] = Node(f[0] + d[0] * a[0], 0);
    	mx2[a[0]].push(Node2(f[0] - d[0] * a[0], d[0], 0));
    	for(int i = 1; i <= n; i++) {
    		int mx, mxp; f[i] = -oo;
    		for(int j = 0; j <= 100; j++) if(vP1[j][i] && P1[j][i].val > mx1[j].val)
    			mx1[j] = P1[j][i];
    		for(int j = 0; j <= 100; j++) if(mx1[j].val > -oo)
    			mx = mx1[j].val, mxp = mx1[j].pos, f[i] = max(f[i], mx - i * j + b[i]);
    		for(int j = 0; j <= 100; j++) if(!mx2[j].empty()) {
    			Node2 u = mx2[j].top();
    			while(u.end < i && !mx2[j].empty()) mx2[j].pop(), u = mx2[j].top();
    			if(u.end >= i) {
    				mx = u.val; mxp = u.pos;
    				f[i] = max(f[i], mx + i * j + b[i]);
    			}
    		}
    		Node v = Node(f[i] + d[i] * a[i], i);
    		if(!vP1[a[i]][d[i]]) vP1[a[i]][d[i]] = 1, P1[a[i]][d[i]] = v;
    		else if(P1[a[i]][d[i]].val < f[i] + d[i] * a[i]) P1[a[i]][d[i]] = v;
    		mx2[a[i]].push(Node2(f[i] - d[i] * a[i], d[i], i));
    //		printf("%d ", f[i]);
    	}
    	
    	printf("%d
    ", f[n]);
    	
    	return 0;
    }
    

    写个全套题解真不容易。。。。。

  • 相关阅读:
    贪婪与非贪婪模式
    Arduino语言介绍
    POJ 3249 记忆化搜索或拓扑排序
    POJ 3177 缩点 + 边双连通图
    POJ 1637 网络流构图
    hdu 1285 拓扑排序+优先队列
    POJ 3160 缩点+拓扑排序+简单dp
    POJ 3592 缩点+拓扑排序+最长路
    针对11级队员的暑假训练计划(初稿)
    POJ 2762 缩点+判断是否是最长链
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5903614.html
Copyright © 2011-2022 走看看