《挑战程序设计竞赛》--初级篇习题POJ部分【动态规划】
关于基本的动态规划和经典的动态规划,在之前已经总结过了,可以温习一下:
传送门
这次是延续上次的《挑战程序设计竞赛》初级篇,总结部分poj上的练习题,主要是DP方面的练习题:
一、基础的动态规划算法
1.Cow Bowing
题目大意:当牛去打保龄球的时候,它们不用真正的保龄球。他们每人取一个数字(范围为0…99),然后排成一个标准的像保龄球针一样的三角形,就像这样:
7*3 8*8 1 0*2 7 4 4* 4 5 2 6 5
然后其他的奶牛从三角形的顶端开始穿过三角形,
“向下”移动到两头相邻的奶牛中的一头,直到到达“底部”那一排。
奶牛的得分是沿途被访问的奶牛数量的总和。得分最高的那头牛就赢了。
给定一个有N (1 <= N <= 350)行的三角形,确定可实现的最大可能和。
思路:入门级的DP问题,就是很简单的DP+穷竭搜索
令dp [i] [N] : 从底下往上加,第i行第N个值 的 最大值
有 dp [i][N] = max(dp [i+1][N] + num[i][N] , dp [i+1][N+1] + num[i][N])
最后加到第一行的值,即为可能实现的最大可能和,
因为dp每次只跟一个状态有关,可以用一维数组。
实现代码:
#include<cstdio>
#define MAX_N 355
int cows[MAX_N][MAX_N]; //记录保龄球三角形
int N;
int dp[MAX_N]; //一维
int max(int x,int y){return x > y ? x : y;
}void solve(){for(int i = 0; i < N - 1;i++){ //计算N-1次,第一次已经计算过了for(int j = 0; j < N - 1 - i;++j){ dp[j] = max(dp[j] + cows[N-2-i][j],dp[j+1] + cows[N-2-i][j]);//从倒二行开始递推} }
}int main(){scanf("%d",&N);for(int i = 0,j = 1;i < N;i++,j++){for(int k = 0; k < j;++k){scanf("%d",&cows[i][k]);if(i == N - 1) //初始化开始状态的dpdp[k] = cows[i][k];}}solve();printf("%d\n",dp[0]);
}
2.Sumset
帮助FJ计算给定整数N (1 <= N <= 1,000,000)的所有可能表示。
由于这个数字可能非常大,所以只打印后9位数字(以10为基数表示)…
#include<cstdio>
#include<algorithm>
#define MAX_N 1000005
using namespace std;
int dp[MAX_N];
int N;void solve(){for(int i = 1;i <= N;++i){ //一个个求,从1开始 if(i & 1 == 1) { //奇数 dp[i] = dp[i-1] % 1000000000;}else {dp[i] = (dp[i-1] % 1000000000 + dp[i >> 1] % 1000000000 )% 1000000000;}}
}int main(){scanf("%d",&N);fill(dp,dp+N+1,0);dp[0] = 1;solve(); printf("%d\n",dp[N] ); //由于这个数字可能非常大,所以只打印后9位数字(以10为基数表示)。一开始没看到WA ,//改成long long 对最后结果取模WA,看来long long不溢出取模 != int溢出取模 是自己理所当然了/* int x = 20000020001;long long y = 20000020001;printf("%d\n",x % 1000000000); printf("%lld\n",y % 1000000000); */ //-474816479 and 20001 确实不同
}
3.Apple Catching
每分钟,两棵苹果树中就会有一棵掉下一个苹果。如果她站在苹果掉下来的树下,她就能抓住苹果。
她任何时候都只能站在一棵树下,而她不愿意无休止地在树之间来回走动(因此会错过了一些苹果)。
#include<cstdio>
#include<algorithm>
#define MAX_T 1005
#define MAX_W 35
using namespace std;
int T[MAX_T];
int dp[MAX_T][MAX_W];
int Ti,W;int max(int x,int y){return x > y ? x : y;
}void solve(){ //计算出dp[T][W] fill(dp[0],dp[0] + MAX_T * MAX_W,0);dp[1][0]=(T[1] == 1 ? 1 : 0);dp[1][1]=(T[1] == 2 ? 1 : 0); //默认已知 for(int i = 2;i <= Ti;++i){dp[i][0] = dp[i-1][0] + (T[i] == 1 ? 1 : 0); // w == 0for(int w = 1;w <= W && w <= i;++w){ //w <= i 这个条件,即跳转数不大于秒数,避免无意义的左右横跳,减少计算量 去掉其实也无妨 dp[i][w] = max(dp[i-1][w-1],dp[i-1][w]) + (T[i] == ((w & 1) + 1) ? 1 : 0); //注意优先级···· + & 先算 + 再算 & ``}}
}int main(){scanf("%d%d",&Ti,&W);for(int i = 1;i <= Ti;++i){ scanf("%d",&T[i]);}solve();printf("%d\n",dp[Ti][W]);
}
4.Miking Time
这里先对所有区间按结束时间从小到大排序!
dp[i] ==> 使用前i+1个时间列表的最大加仑数
dp[i] = max(dp[i - 1], dp[tmp] + fj[i].e);
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll; //int可能溢出
#define MAX_M 1005
#define MAX_N 1000005
int N,M,R;
ll dp[MAX_M];
struct FJ{int s,f,e;//start finsh efficiency
};bool cmp(const FJ& x,const FJ& y){return x.f < y.f; //按结束时间从小到大
}FJ fj[MAX_M];ll max(ll x,ll y){return x > y ? x : y;
}void solve(){dp[0] = 0; for (int i = 1; i <= M; i++) {//tmp是与区间i前最接近的区间序号 int tmp; for(tmp = i - 1;tmp > 0;) {if(fj[tmp].f + R > fj[i].s)tmp--;else break; }dp[i] = max(dp[i - 1], dp[tmp] + fj[i].e);//printf("%d,%d,%d\n",i,dp[i],tmp) ;}printf("%d\n",dp[M]);
}int main(){scanf("%d%d%d",&N,&M,&R);for(int i = 1;i <= M;++i){scanf("%d%d%d",&fj[i].s,&fj[i].f,&fj[i].e);}sort(fj+1,fj+M+1,cmp); //先排序,结束时间从小到大solve(); return 0;
}
5.Cheapest Palindrome
#include<cstdio>
#include<algorithm>
#include<String>
using namespace std;
#define MAX_M 2050
#define INF 10000000
int N,M;
char s[MAX_M];
int letter[26];
int dp[MAX_M][MAX_M];int min(int x,int y){return x < y ? x : y;
}void solve(){//dp [i][j] 为区间i到j变成回文的最小代价if(M == 1 || M == 0){printf("0\n");return;} for(int i = M-2;i >= 0;--i){ //倒二位置开始看 逆序for(int j = i + 1;j < M;++j) // 从左逐渐往右,从内往外 正序{if(s[i] == s[j])dp[i][j] = dp[i+1][j-1];else dp[i][j] = min( dp[i+1][j] + letter[s[i]-'a'], dp[i][j-1] + letter[s[j]-'a'] );}}printf("%d\n",dp[0][M-1]);
}int main(){scanf("%d%d",&N,&M);scanf("%s",s);getchar(); //吃掉回车 for(int i = 0;i < N;++i){char c;int a,b;scanf("%c %d %d",&c,&a,&b);//printf("%c %d %d\n",c,a,b);//删除跟添加一样 。例如 abcb 你要删a 跟在后面加a是一样的 letter[ c-'a'] = min(a,b);getchar(); //吃掉回车 }solve();return 0;
}
二、优化递推关系式
1.Coins
题目大意:
给定N个硬币,包括数量、价值,(1<=N<=100) , (M<=100000)
求使用这些硬币能够支付不超过M元的支付方式有多少种
#include <cstdio>
#include <cstring>
using namespace std;int n,m;
int w[105],c[105],sum[100005],dp[100005];
//必须用一维数组,不然空间爆炸int main()
{while(~scanf("%d%d",&n,&m)){if(n==0 && m==0)break;for(int i=0;i<n;i++){scanf("%d",&w[i]);}for(int i=0;i<n;i++){scanf("%d",&c[i]);}memset(dp,0,sizeof(dp));dp[0]=1;int ans=0;for(int i=0;i<n;i++) //n种物品 {// sum[j]表示填充j大小的包需要至少使用多少个当前物品memset(sum,0,sizeof(sum)); for(int j=w[i];j<=m;j++) // 完全背包的一维数组,正向状态转化{if(!dp[j] && dp[j-w[i]] && sum[j-w[i]] < c[i]) //dp[j]表示填充为j是否可行,如果dp[j] = 0表示不可行,那么看 dp[j-w[i]](之前是不是有组合可行) 可行的话同时看当前物品是否够放 {dp[j]=1;sum[j] = sum[j-w[i]] + 1;//更新 ans++; //组合数+1}}}printf("%d\n",ans);}return 0;
}
2.Ant Counting
#include<cstdio>
#include<algorithm>
#define MAX_T 1005
#define MAX_A 100005
#define MOD 1000000
using namespace std;
int T,A,S,B;
int ans[MAX_T];
//int dp[MAX_T][MAX_A] ; //这样写铁定超内存,可以用滚动数组,因为 dp[i+1][j] 只跟自己和上一行有关
int dp[2][MAX_A]; //滚动数组 void solve(){//一个都不取只有一种取法//for(int i = 0;i <= T; ++i){// dp[i][0] = 1;//}dp[0][0] = 1;dp[1][0] = 1;int res = 0;for(int i = 0;i < T; ++i){for(int j = 1;j <= B;++j){if(j - 1 - ans[i] >= 0){//dp[i+1][j] = dp[i+1][j-1] + dp[i][j] - dp[i][j - 1 - ans[i]];dp[(i+1) & 1][j] = (dp[(i+1) & 1][j-1] + dp[i & 1][j] - dp[i & 1][j - 1 - ans[i]] + MOD) % MOD; //取模有减法 +MOD在取MOD 避免减法出现负数,取模也为负数的情况 }else {//dp[i+1][j] = dp[i+1][j-1] + dp[i][j];dp[(i+1) & 1][j] = (dp[(i+1) & 1][j-1] + dp[i & 1][j]) % MOD;} }}for (int i = S; i <= B; i++) //把 S~B 的所有取法都加上res = (res + dp[T & 1][i]) % MOD; //这里用 res += 的话,后头还需要补一句 res %= mod一下防溢出 ,因为这个贡献了几次WA//printf("%d %d\n",dp[T][B],dp[T][S]);printf("%d\n",res);
}int main(){scanf("%d%d%d%d",&T,&A,&S,&B);for(int i = 0;i < A;++i){int num;scanf("%d",&num);ans[num-1]++;}solve();
}
3.Dollar Dayz
题目大意:
给定N元,K件商品,商品价值从1 ~ K(1,2,3,…K) ;
n <= 1000 , k <= 100
请问 给定 N,K能够得到多少种购买方式 ?
#include <cstdio>
#include <algorithm>
#include <string>
#define MAX_W 100
#define MAX_N 1005
using namespace std;
struct BigInteger {char digit[MAX_W];int length;BigInteger();BigInteger operator=(int x);BigInteger operator=(string s);BigInteger operator=(const BigInteger& b);BigInteger operator+(const BigInteger& b);
}; BigInteger::BigInteger(){fill(digit,digit+MAX_W,'0');length = 0;
}BigInteger BigInteger::operator=(int x){fill(digit,digit+MAX_W,'0');length = 0;if(x == 0){digit[length++] = '0';}while(x != 0){digit[length++] = (char)('0' + x % 10);x /= 10;}return *this;
}BigInteger BigInteger::operator=(string s){fill(digit,digit+MAX_W,'0');length = s.size();for(int i = 0;i < length; ++i){digit[i] = s[length - i - 1];}return *this;
}BigInteger BigInteger::operator=(const BigInteger& b){fill(digit,digit+MAX_W,'0');length = b.length;for(int i = 0;i < length;++i){digit[i] = b.digit[i];}return *this;
}BigInteger BigInteger::operator+(const BigInteger& b){BigInteger ans;int carry = 0;for(int i = 0;i < length || i < b.length;++i){//当前位计算,长的位由于短的没有,短的默认没有的都是0 int current = carry + (digit[i] - '0') + (b.digit[i] - '0'); carry = current / 10;ans.digit[ans.length++] = (char)('0' + current % 10);}if(carry != 0){ //最后一位有进位 ans.digit[ans.length++] = (char)('0' + carry); }return ans;
}void printB(const BigInteger& b){if(b.length == 0){printf("0\n");return;}for(int i = b.length - 1;i >=0 ;--i)printf("%c",b.digit[i]);printf("\n");
}//BigInteger dp[]
BigInteger dp[MAX_N];
int N,K;void solve(){dp[0] = 1;for(int i = 1;i <= K;++i){for(int j = i; j <= N;++j){ //从i开始因为j < i的没有改变
// printB(dp[j] + dp[j - i]);dp[j] = dp[j] + dp[j - i]; //dp[i][j] = dp[i-1][j] + dp[i][j - i]}}printB(dp[N]);
}int main(){scanf("%d%d",&N,&K);solve();
// BigInteger a;
// a = "11111111111111111111";
printB(a);
// BigInteger b;
// b = "11111111111111111111";
// a = a + b;
// printB(a);return 0;
}
大数相加采用的 用char数组存大数的每一位···写的比较通用,但是就这道题来说复杂了
因为大佬发现把数据取满了 N = 1000,K = 100的购买方式也就这么大:
15658181104580771094597751280645 (两个long long就可以存下)
/*
用两个数组,第一个数组保存的是方法数的前1e18个数,
第二个数组保存的是方法数的后1e18个数字,那么就可以保存1e36位的方法数。
为啥取1e18呢?因为long long大概就是在1e19这个数量级,所以取到1e18可以防止溢出
*/#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1010;
const LL INF = 1e18;
LL dp1[MAXN], dp2[MAXN];
int main()
{int n, k;scanf("%d %d", &n, &k);dp2[0] = 1;for(int i = 1;i <= k;++i){for(int j = i;j <= n;++j){dp1[j] = dp1[j] + dp1[j - i] + (dp2[j] + dp2[j - i]) / INF; //高18位 dp2[j] = (dp2[j] + dp2[j - i]) % INF; //高17位 }}if(dp1[n])printf("%I64d", dp1[n]);printf("%I64d\n",dp2[n]);return 0;
}
三、需稍加思考的题目
1.Wooden Sticks
- 每次从一个尚未被使用的木头出发,依次找到没有被使用且w 非递减(因为l肯定满足非递减了)的子序列 直到遇到 减小的w,划分加一;
- 因为每次贪心划分都能得到一个极大的 非下降子序列,虽然极大不一定是最大,但是每次都能划分出不重复的极大,每次划分之间没有影响,最终划分肯定是最少的。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<functional>
using namespace std;
#define MAX_N 5000
int T,N;
struct Wooden{int l,w;
};
Wooden wooden[MAX_N];
int dp[MAX_N] ;
// 两种理解: 以i为尾部的最大的下降子序列solve or 长度为i的下降子序列末尾元素的最小值solve2bool cmp(const Wooden& x,const Wooden& y){if(x.l == y.l)return x.w < y.w;else return x.l < y.l;
}
void solve(){ //dp o(N^2) 可优化为 o(N*lgn) memset(dp,0,sizeof(dp) );int res = 0;for(int i = 0;i < N;++i){dp[i] = 1;//初始化为只包含aifor(int j = 0;j < i;++j){if(!(wooden[i].l >= wooden[j].l && wooden[i].w >= wooden[j].w) ){ //a[i] < a[j]dp[i] = max(dp[i],dp[j] + 1);}}res = max(res,dp[i]);}printf("%d\n",res);
}void solve2(){ // o(N*lgn) memset(dp, -1, N * sizeof(int));for (int i = 0; i < N; ++i){*lower_bound(dp, dp + N, wooden[i].w, greater<int>()) = wooden[i].w;//常用的逆序可以加载头文件#include<functional>,里边有一个greater<int>()函数即可对逆序求最近位置。}printf("%d\n",lower_bound(dp, dp + N, -1, greater<int>()) - dp); // 第一个 -1前都是更新了有值的~
} int main(){scanf("%d",&T);for(int i = 0;i < T;++i){scanf("%d",&N); for(int j = 0;j < N;++j){scanf("%d%d",&wooden[j].l,&wooden[j].w);}sort(wooden,wooden+N,cmp);//solve();solve2();}return 0;
}
2.Bridging signals
题目大意:
新来的实习生把路由线路搞得一团糟!原本左右端口应当按顺序连接吗,但现在出现了交叉;现在只有切除部分线路,使得任何线路都不相交。希望你写一个程序计算最后最多剩下多少线路?
#include<cstdio>
#include<algorithm>
#define MAX_P 40005
#define INF 100000
using namespace std;
int dp[MAX_P]; //长度为i+1的递增子序列末尾元素的最小值
int T,P;
int port[MAX_P];// 可以自己实现二分查找
int binary_search(int left,int right,int path)
{ int mid;while(left<=right){mid=(left+right)/2;if(list[mid] < path) left = mid+1;else right = mid-1;}return left;//输出大于等于num的最小的数的位置
} void solve(){fill(dp,dp+P,INF);//INF表示没有for(int i = 0;i < P;++i){ //从长度1开始 *lower_bound(dp,dp+P,port[i]) = port[i]; //STL支持的二分查找}printf("%d\n",lower_bound(dp,dp+P,INF) - dp);
}int main(){scanf("%d",&T);for(int i = 0;i < T;++i){scanf("%d",&P);for(int j = 0;j < P;++j)scanf("%d",&port[j]);solve(); }
}
3.Making the Grade
实现代码:(以下代码在 更深的测试上提交了,那个必须用long long)
#include<cstdio>
#include<algorithm>
#define MAX_N 5005
using namespace std;
//int dp[MAX_N][MAX_N];
typedef long long LL;
LL dp[6005];//一维数组
int N;
LL A[6005],B[6005];
LL min_cost = INF;
LL min(LL x,LL y){return x < y ? x : y;
}
LL Abs(LL a)
{if(a >= 0)return a;else return -a;
}
bool cmp(LL x,LL y)
{return x > y ; // x > y ? x : y 开始写出这样导致 疯狂 RE····
}void solve2(){ //利用状态转移 写出一维数组 ,或者 2个数组的滚动数组 空间
// //这里是非递减的最小代价 POJ数据较弱只写非递减的代码就能过了```sort(B,B+N); //递增,小的先选for(int i = 0; i < N; i++) //初始化,当 dp[0][j] 只使用第一块土地 dp[i]= Abs(A[0] - B[i]);for(int i = 1;i < N;++i){LL min_dp = dp[0];for(int j = 0;j < N;++j){min_dp = min(min_dp,dp[j]); // 记录j以前的最小值 dp[j] = Abs(B[j] - A[i]) + min_dp;}}LL min_cost = dp[0];for(int i = 0;i < N;++i){min_cost = min(min_cost,dp[i]);}//____________________________这里是非递增 ··· 区别就在于逆序排序·sort(B,B+N,cmp); //递减,大的先选for(int i= 0; i < N; i++) //初始化dp[i]= Abs(A[0] - B[i]);for(int i = 1;i < N;++i){LL min_dp = dp[0];for(int j = 0;j < N;++j){min_dp = min(min_dp,dp[j]); // 记录j以前的最小值 dp[j] = Abs(B[j] - A[i]) + min_dp;}}LL ANS = dp[0];for(int i=0; i<N; i++)ANS=min (dp[i],ANS);min_cost = min(min_cost,ANS);printf("%lld\n",min_cost);
} int main()
{scanf("%d",&N);for(int i = 0;i < N;++i){scanf("%lld",&A[i]);B[i] = A[i];}solve2();
}
4.Space Elevator
只不过重量变成了高度限制 ~
dp[ i ][ j ] :前i种木头能否能到 j 高度
dp[ i ][ j ] = dp[ i-1 ][ j ] || dp[ i-1 ][ j - h[ i ] ]
#include<cstdio>
#include<algorithm>
#define MAX_K 405
#define MAX_A 40005
struct Wooden{int h,a,c;
};
Wooden wooden[MAX_K];
Wooden wooden_01[MAX_K * 4];
using namespace std;
int K;
bool cmp(const Wooden& x,const Wooden& y){return x.a < y.a;
}
bool dp[MAX_A];//表示这种高度可以达到 int main(){scanf("%d",&K);int number01 = 0;for(int i = 0;i < K;++i){scanf("%d%d%d",&wooden[i].h,&wooden[i].a,&wooden[i].c); int num = wooden[i].c;for(int j = 1;j <= num;j *= 2){ // 拆分为 0 / 1wooden_01[number01].a = wooden[i].a;wooden_01[number01++].h = j * wooden[i].h; //长度组合 num -= j; }if(num > 0){wooden_01[number01].a = wooden[i].a;wooden_01[number01++].h = num * wooden[i].h; //长度组合}}sort(wooden_01,wooden_01+number01,cmp); fill(dp,dp+MAX_A,false); dp[0] = true;//初始化 到达0高度肯定可以int max_highest = 0; for(int i = 0;i < number01;++i){ //对0/1的每个背包 for(int j = wooden_01[i].a;j >= wooden_01[i].h;j--){ if(dp[j - wooden_01[i].h]) { //如果不拿这个背包可以达到 dp[j] = true;max_highest = (max_highest > j ? max_highest : j);}}}printf("%d\n",max_highest);
}
5.Cow Exhibition
#include<cstdio>
#include<algorithm>
#define MAX_N 105
#define MAX_S 1005
#define INF 10000000
using namespace std;
struct Cow{int Si,Fi;
};
Cow cows[MAX_N];
int N;
int dp[MAX_N * MAX_S * 2]; //为了避免出现负数下标,扩大数组,以中心为原来的dp[0] void solve(){fill(dp,dp+MAX_N * MAX_S * 2,-INF);//初始化,因为价值有负的,所以初始化为所有负值加起来都不能达到的一个数 dp[MAX_N * MAX_S] = 0;//右移后的原点,相当于没有重量时的价值 for(int i = 0; i < N;++i){if(cows[i].Si > 0) // dp[i][j] = max(dp[i-1][j],dp[i-1][j - Si] + Fi) j - Si小于j 为确保关系转移逆向走 {for(int j = MAX_N * MAX_S * 2 - 1; j >= cows[i].Si;--j){dp[j] = max(dp[j],dp[j - cows[i].Si] + cows[i].Fi); } }else { //j - Si > j 为确保关系转移正向走 for(int j = 0; j < MAX_N * MAX_S * 2 + cows[i].Si; ++j){dp[j] = max(dp[j],dp[j - cows[i].Si] + cows[i].Fi); } }} int res = -INF;//由于我们这题的价值是fi + Si,需要遍历一下 (由于原点我们更换了,所以这里我们也得更换一,这样确保Si都是不小于0的 ) for (int i = MAX_N * MAX_S;i < MAX_N * MAX_S * 2;i++){if(dp[i] >= 0) //Fi大于0 res = max(res,dp[i] + i - MAX_N * MAX_S); //fi + Si } if(res <= 0)printf("%d\n",0);else printf("%d\n",res);}
int main(){scanf("%d",&N);for(int i = 0;i < N;++i){scanf("%d%d",&cows[i].Si,&cows[i].Fi);}solve();return 0;
}
以上就是《挑战程序设计竞赛》–初级篇习题POJ部分【动态规划】习题,题目还是挺不错的,很适合新手入门级的DP练习…就是 有些题坑还是比较多的
(能力有限,如有错误 ,还望指出)
《挑战程序设计竞赛》--初级篇习题POJ部分【动态规划】相关推荐
- 《挑战程序设计竞赛》--初级篇习题POJ部分【2.4 - 2.6】
这次是延续上次的<挑战程序设计竞赛>初级篇,总结部分poj上的练习题,主要是2.4 ~ 2.6部分: 导航 2.4 加工并存储的数据结构 优先队列 Sunscreen MooUnivers ...
- 《挑战程序设计竞赛》--初级篇习题POJ部分【穷竭搜索+贪心】
最近看了<挑战程序设计竞赛>初级篇,这里总结一下部分poj上的练习题,主要涉及方面为: 穷竭搜索 and 贪心算法 具体题目: 简单导航 一.穷竭搜索 二.贪心算法 一.穷竭搜索 穷竭搜索 ...
- POJ 1150 The Last Non-zero Digit 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 1150 The Last Non-zero Digit超大组合数:求超大组合数P(n, m)的最后一个非零位.4.1更加复杂 ...
- POJ 3735 Training little cats 题解 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 3735 Training little cats调教猫咪:有n只饥渴的猫咪,现有一组羞耻Play,由k个操作组成,全部选自: ...
- POJ 3608 Bridge Across Islands 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 3608 Bridge Across Islands跨岛大桥:在两个凸包小岛之间造桥,求最小距离?3.6与平面和空间打交道的计 ...
- POJ 3713 Transferring Sylla 题解 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 3713 Transferring Sylla三连通图:判断一个无向图是否三连通?3.5借助水流解决问题的网络流最大流刷个题报 ...
- 挑战程序设计竞赛(第二章习题总结)
文章目录 搜索 Curling 2.0(POJ 3009) Meteor Shower(POJ 3669) Smallest Difference(POJ 2718) Hopscotch(POJ 30 ...
- POJ 1418 Viva Confetti 题解 《挑战程序设计竞赛》
为什么80%的码农都做不了架构师?>>> POJ 1418 Viva Confetti礼花:Confetti 是一些大小不一的彩色圆形纸片,人们在派对上.过节时便抛洒它们以示庆 ...
- 挑战程序设计竞赛(第2版)》
<挑战程序设计竞赛(第2版)> 基本信息 作者: (日)秋叶拓哉 岩田阳一 北川宜稔 译者: 巫泽俊 庄俊元 李津羽 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787 ...
最新文章
- Spark源码阅读03-Spark存储原理之序列化和压缩
- dataframe常用操作_【Data Mining】机器学习三剑客之Pandas常用算法总结上
- ios rsa java_一篇搞定RSA加密与SHA签名|与Java完全同步
- 二、PHP框架Laravel学习笔记——路由的定义和控制器
- 华为P40 Pro将搭载索尼IMX 700传感器:支持十六像素合一
- java arraylist 构造_深入理解java集合框架之---------Arraylist集合 -----构造函数
- WinForm框架开发教程 - 如何实现简单化开发?
- [渝粤教育] 南京审计大学 审计学基础 参考 资料
- pcsx2运行ps1_PS2模拟器PSX2设置及使用教程.doc
- 我用Vue3+TS实现了一个新年倒计时组件,适用于各种场景
- 史上MySQL安装配置教程最细,一步一图解
- Android人脸支付功能,终于来了,华为Mate20 Pro微信人脸支付功能已上线
- 此生未完成 --- 于娟
- ubuntu18.04 使用scp命令
- 【聚水潭SDK使用说明】
- Eureka 健康检查
- 细数那些最令人难忘的电视剧
- 今年十月最新语言排行榜
- C++中的reverse()函数
- python图像处理(图像缩放)
热门文章
- 用计算机在作文格中打单字字,描写一个字的作文
- redshift 踩坑
- Elasticsearch:Rank feature query - 排名功能查询
- 时间序列回归模型(Forecasting: Principles and practice第六章)
- TCP协议详解(一) TCP服务的特点和TCP头部结构
- 卡牌系统psv游戏推荐_PSV精品游戏推荐之一,让你的小V再次发挥余热吧!
- 刚出道的黑客搞瘫美国输油管道!
- Sequelize 大于_巴菲特买股三原则:毛利率大于30%+ROE大于15%+现金流大于100%
- 实现字典树(前缀树、Trie树)并详解其应用
- cmake 安装下载