[DP魔炼][DP] DP随练随学(疯狂A题训练——DP基础篇 题解 下)

终于写完啦!!!!!!!!

T28 最大子段和

传送门
维护前缀和
找前面最小的

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
const int INF=2147483647;
int n,a[N],p[N];

int main(){
	n=in;
	for(int i=1;i<=n;++i) a[i]=a[i-1]+in;
	int tmp=INF,id=0;
	for(int i=1;i<=n;++i){
		p[i]=id;
		if(a[i]<tmp) id=i,tmp=a[i];
	}
	tmp=-INF;
	for(int i=1;i<=n;++i) tmp=max(tmp,a[i]-a[p[i]]);
	printf("%d\n",tmp);
	return 0;
}

交上去一波发现80pts
究其原因:只关注前面最值不够

考虑贪心
维护前缀和,但是前缀和不优秀就直接取此数

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
const int INF=2147483647;
int n,a[N],p[N],ans=-INF;

int main(){
	n=in;
	for(int i=1;i<=n;++i) a[i]=in;
	for(int i=1;i<=n;++i){
		p[i]=max(p[i-1]+a[i],a[i]);
		ans=max(ans,p[i]);
	}
	cout<<ans<<endl;
	return 0;
}

TOP

T29 路径计数2

Portkey
棋盘型DP

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e3+5,M=1e5+5,mod=1e5+3;
int n,m,f[N][N];
bool b[N][N];

int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}

int main(){
	n=in,m=in;
	for(int i=1;i<=m;++i){
		int x=in,y=in;
		b[x][y]=true;
	}
	f[1][1]=1;
	for(int x=1;x<=n;++x)
		for(int y=1;y<=n;++y){
			if(b[x][y]||(x==1&&y==1)) continue;
			f[x][y]=add(f[x-1][y],f[x][y-1]);
		}
	printf("%d\n",f[n][n]);
	return 0;
}

TOP

T30 [USACO1.5][IOI1994]数字三角形 Number Triangles

Portkey

IOI1994?
就这就这?

好像是第一道看的DP题
(当然当时很菜)

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e3+5;
int n,a[N][N],f[N][N],ans=-2147483647;

int main(){
	n=in;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=i;++j)
			a[i][j]=in;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j];
		}
	for(int i=1;i<=n;++i)
		ans=max(ans,f[n][i]);
	cout<<ans<<endl;
	return 0;
}

TOP

T31 【模板】最长公共子序列

Portkey

LCS板题
考虑维护 f [ i ] [ j ] f[i][j] f[i][j]表示第一个数列第i位前和第二个数列第j位前的LCS

菜至极
只会 n 2 n^2 n2

考虑转化
这是个排列,就可以搞事情
把一个数列的数变成下标,相应的替换另一个数列里的数
这样不会改变两个数列LCS的本质
转化后发现只需要求另一个数列的LIS(最长上升子序列)了

LIS当然用单调队列优化
优秀✌️

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e5+5;
int n,a[N],b[N],q[N],len=1;

int main(){
	n=in;
	for(int i=1;i<=n;++i) a[in]=i;
	for(int j=1;j<=n;++j) b[j]=a[in];
	q[1]=b[1];
	for(int i=1;i<=n;++i){
		if(b[i]>q[len]){q[++len]=b[i];continue;}
		int pos=lower_bound(q+1,q+len+1,b[i])-q;
		q[pos]=min(q[pos],b[i]);
	}
	printf("%d\n",len);
	return 0;
}

TOP

T32 友好城市

Portkey

本来今天排到一道数位DP的
但是数位DP我自己准备了好多题
就咕了
过两天做专题

NOIP做过
双倍经验

双倍经验个鬼
后面50pts卡 n 2 n^2 n2

二分图呗
二分图个鬼
人家求的是航道不交叉qwq

发现:
两条航线起点终点都是小于或大于,航线不相交
对起点排序
求终点的最长不下降序列
单调队列优化

有点淦的是
不知道为什么记录单调队列长度siz的历史最大值就不对qwq
求巨佬解释

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
int n,f[N],q[N],siz=1,ans;
struct node{
    int u,v;
}p[N];

bool cmp(const node a,const node b){
    return a.u<b.u;
}

int main(){
    n=in;
    for(int i=1;i<=n;++i) p[i].u=in,p[i].v=in;
    sort(p+1,p+n+1,cmp);
	q[1]=p[1].v;
	for(int i=2;i<=n;++i){
		if(p[i].v>q[siz]){q[++siz]=p[i].v;continue;}
		int pos=lower_bound(q+1,q+siz+1,p[i].v)-q;
		q[pos]=min(q[pos],p[i].v);
	}
	printf("%d\n",siz);
    return 0;
}

TOP

T33 旅行计划

Portkey

单源单汇就是最长路
多源单汇就是反一下最长路
多源多汇就是拓扑排序

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
int n,m,deg[N],f[N];
vector<int>G[N];

void topo(){
	queue<int>q;
	for(int i=1;i<=n;++i) if(!deg[i]) q.push(i),f[i]=1;
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int e=0;e<G[u].size();++e){
			int v=G[u][e];
			--deg[v];
			f[v]=max(f[v],f[u]+1);
			if(!deg[v]) q.push(v);
		}
	}
	return;
}

int main(){
	n=in,m=in;
	for(int i=1;i<=m;++i){
		int u=in,v=in;
		G[u].push_back(v);
		++deg[v];
	}
	topo();
	for(int i=1;i<=n;++i) printf("%d\n",f[i]);
	return 0;
}

TOP

T34 [USACO09DEC]Dizzy Cows G

Portkey

考察最后图的性质:DAG
联想到拓排
拓排要求DAG,如果在排的时候强行整成DAG呢
是可以的

于是按有向边拓排
遇到无向边将它改造为从这个点出发的有向边
一通暴搞下来得到的就是DAG

题目的

数据保证一开始就有的单向道路中

就很优秀
而且保证有解

#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
int n,m1,m2;
int tot,first[N],nxt[N],aim[N],wei[N],ori[N];
int deg[N];
queue<int>q;

void ljb(int u,int v,int w){
	++tot;
	nxt[tot]=first[u];
	first[u]=tot;
	aim[tot]=v;
	ori[tot]=u;
	wei[tot]=w;
	return;
}

signed main(){
	// freopen("IN.in","r",stdin);
	// freopen("out.out","w",stdout);
	n=in,m1=in,m2=in;
	for(int i=1;i<=m1;++i){
		int u=in,v=in;
		ljb(u,v,0);
		++deg[v];
	}
	for(int i=1;i<=n;++i) if(!deg[i]) q.push(i);
	if(!(tot&1)) ++tot;
	for(int i=1;i<=m2;++i){
		int u=in,v=in;
		ljb(u,v,1);
		ljb(v,u,1);
	}
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int e=first[u];e;e=nxt[e])
			if(!wei[e]){
				int v=aim[e];
				--deg[v];
				if(!deg[v]) q.push(v);
			}
		for(int e=first[u];e;e=nxt[e])
			if(wei[e]==1) wei[e^1]=2;
	}
	for(int i=1;i<=n;++i) if(deg[i]){puts("-1");return 0;}
	bool flag=false;
	for(int i=1;i<=tot;++i)
		if(wei[i]==1)
			printf("%lld %lld\n",ori[i],aim[i]),flag=true;
	if(!flag) puts("-1");
	return 0;
}

这第10个点。。。
invalid answer

top

T35 [HAOI2016]食物链

Portkey

不科学!
他没说食物链是随便一条链还是入度0到出度0的链!

设入度0的点有 x x x个,总共 n n n个点
那么从每个入度进去遍历整张图 O ( x ( n − x ) ) O(x(n-x)) O(x(nx))
可能T掉

考虑记搜
记录每个点上能到达出度0点的个数
这个值是一定的,可以记搜
优化至 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
int n,m;
int tot,first[N],nxt[N],aim[N];
int indeg[N],outdeg[N],f[N];

void ljb(int u,int v){
	++tot;
	nxt[tot]=first[u];
	first[u]=tot;
	aim[tot]=v;
	return;
}

int DFS(int u){
	if(f[u]) return f[u];
	if(!outdeg[u]) return 1;
	int ans=0;
	for(int e=first[u];e;e=nxt[e]){
		int v=aim[e];
		ans+=DFS(v);
	}
	return f[u]=ans;
}

int main(){
	n=in,m=in;
	for(int i=1;i<=m;++i){
		int x=in,y=in;
		ljb(x,y);
		++indeg[y];
		++outdeg[x];
	}
	int ans=0;
	for(int i=1;i<=n;++i)
		if(!indeg[i]&&outdeg[i])
			ans+=DFS(i);
	printf("%d\n",ans);
	return 0;
}

T36 最大食物链计数

Portkey

双倍经验

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e6+5;
const int mod=80112002;
int n,m;
int tot,first[N],nxt[N],aim[N];
int indeg[N],outdeg[N],f[N];

int add(int a,int b){return a+b>mod?a+b-mod:a+b;}

void ljb(int u,int v){
	++tot;
	nxt[tot]=first[u];
	first[u]=tot;
	aim[tot]=v;
	return;
}

int DFS(int u){
	if(f[u]) return f[u];
	if(!outdeg[u]) return 1;
	int ans=0;
	for(int e=first[u];e;e=nxt[e]){
		int v=aim[e];
		ans=add(ans,DFS(v));
	}
	return f[u]=ans;
}

int main(){
	n=in,m=in;
	for(int i=1;i<=m;++i){
		int x=in,y=in;
		ljb(x,y);
		++indeg[y];
		++outdeg[x];
	}
	int ans=0;
	for(int i=1;i<=n;++i)
		if(!indeg[i]&&outdeg[i])
			ans=add(ans,DFS(i));
	printf("%d\n",ans);
	return 0;
}

Top

T37 绿豆蛙的归宿

Portkey

期望概率DP
考虑
f i = ∑ ( p [ i → j ] f [ j ] + w [ i → j ] ) f_i=\sum (p[i\to j]f[j]+w[i\to j]) fi=(p[ij]f[j]+w[ij])

对于一个点,从它的所有终点走过来
终点期望有累加,边权要考虑
f u = ∑ u → v ( f v + w e ) p e f_u=\sum_{u\to v} (f_v+w_e)p_e fu=uv(fv+we)pe

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=2e5+5;
int n,m;
int tot,first[N],nxt[N],aim[N],wei[N];
double f[N];
int ind[N],siz[N];

void ljb(int u,int v,int w){
	++tot;
	nxt[tot]=first[u];
	first[u]=tot;
	aim[tot]=v;
	wei[tot]=w;
	return;
}

void topo(){
	queue<int>q;
	q.push(n);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int e=first[u];e;e=nxt[e]){
			int v=aim[e];
			f[v]+=(f[u]+1.0*wei[e])/siz[v];
			if(!(--ind[v])) q.push(v);
		}
	}
	return;
}

int main(){
	n=in,m=in;
	for(int i=1;i<=m;++i){
		int u=in,v=in,w=in;
		ljb(v,u,w);
		++ind[u];
		++siz[u];
	}
	topo();
	printf("%.2lf\n",f[1]);
	return 0;
}

TOP

T38 The least round way

Portkey

2 × 5 = 10 ; x ⋅ 0 = 0 2\times 5=10;x\cdot 0=0 2×5=10;x0=0
情况1:统计2,5个数, a n s = min ⁡ ( 2 n , n , 5 n , n ) ans=\min(2_{n,n},5_{n,n}) ans=min(2n,n,5n,n)
情况2:找到0的路径,答案恒为1。
a n s = min ⁡ ( 1 , a n s ) ans=\min(1,ans) ans=min(1,ans)

输出路径考虑递归
情况2直接干

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e3+5,INF=2147483647;
int n,a[N][N][2],f[N][N][2],ans,_x,t;

void print(int x,int y,int k){
	if(x==1&&y==1){putchar(k?'D':'R');return;}
	if(x==1) print(x,y-1,0);
	else if(y==1) print(x-1,y,1);
	else if(f[x][y][t]==f[x][y-1][t]+a[x][y][t]) print(x,y-1,0);
	else print(x-1,y,1);
	if(x!=n||y!=n){putchar(k?'D':'R');return;}
}

int main(){
	n=in;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			int x=in;
			if(!x) _x=i;
			else{
				while(!(x&1)) ++a[i][j][0],x>>=1;
				while(!(x%5)) ++a[i][j][1],x/=5;
			}
		}
	for(int i=1;i<=n;++i)
		f[0][i][0]=f[0][i][1]=f[i][0][0]=f[i][0][1]=INF;
	f[1][1][0]=a[1][1][0];
	f[1][1][1]=a[1][1][1];
	for(int k=0;k<=1;++k)
		for(int i=1;i<=n;++i)
			for(int j=(i==1?2:1);j<=n;++j)
				f[i][j][k]=min(f[i-1][j][k],f[i][j-1][k])+a[i][j][k];
	ans=min(f[n][n][0],f[n][n][1]);
	if(_x&&ans>1){
		puts("1");
		for(int i=1;i<_x;++i) putchar('D');
		for(int i=1;i<n;++i) putchar('R');
		for(int i=_x;i<n;++i) putchar('D');
	}else{
		printf("%d\n",ans);
		t=!(f[n][n][0]<f[n][n][1]);
		print(n,n,0);
	}
	puts("");
	return 0;
}

Top

T39 Writing Code

Portkey

500 500 500的数据范围就很奇怪
大概是个三次算法

一看题,像个背包
n n n种物品,每种无限个,两种体积:
第一种每个物品体积1,容积 m m m,需完全;
第二种每个物品体积 a i a_i ai,容积 b b b,不需完全
O ( n m b ) O(nmb) O(nmb)

注意累计方案数和求最大价值有区别
最大价值是求max,方案数是累加

最终输出的不是出错b个的,而是出错b个以下的

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=505;
int n,m,b,a[N],mod;
int f[N][N];

int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}

int main(){
	n=in,m=in,b=in,mod=in;
	for(int i=1;i<=n;++i) a[i]=in;
	f[0][0]=1;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			for(int k=a[i];k<=b;++k)
				f[j][k]=add(f[j][k],f[j-1][k-a[i]]);
	int ans=0;
	for(int i=0;i<=b;++i) ans=add(ans,f[m][i]);
	printf("%d\n",ans);
	return 0;
}

TOP

T40 尼克的任务

Portkey

倒着加

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=1e5+5;
int n,m,sum[N],f[N],cnt=1;
struct Data{
	int p,t;
}d[N];

bool cmp(const Data &u,const Data &v){return u.p>v.p;}

int main(){
	n=in,m=in;
	for(int i=1;i<=m;++i){
		d[i].p=in,d[i].t=in;
		++sum[d[i].p];
	}
	sort(d+1,d+m+1,cmp);
	for(int i=n;i>=1;--i){
		if(!sum[i]) f[i]=f[i+1]+1;
		else for(int j=1;j<=sum[i];++j){
			if(f[i]<f[i+d[cnt].t])
				f[i]=f[i+d[cnt].t];
			++cnt;
		}
	}
	printf("%d\n",f[1]);
	return 0;
}

T41 字串距离

Portkey

两个东西
考虑 f [ i ] [ j ] f[i][j] f[i][j]直接递推

注意预处理:全是空格的情况

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=3e3+5;
char a[N],b[N];
int k,la,lb,f[N][N];

int main(){
	scanf("%s%s",a+1,b+1);
	k=in;
	la=strlen(a+1),lb=strlen(b+1);
	for(int i=1;i<=la;++i) f[i][0]=f[i-1][0]+k;
	for(int j=1;j<=lb;++j) f[0][j]=f[0][j-1]+k;
	for(int i=1;i<=la;++i)
		for(int j=1;j<=lb;++j){
			f[i][j]=min(min(f[i-1][j]+k,f[i][j-1]+k),f[i-1][j-1]+abs(a[i]-b[j]));
		}
	printf("%d\n",f[la][lb]);
	return 0;
}

T42 NAPTIME - Naptime

Portkey

f [ i ] [ j ] [ 0 / 1 ] f[i][j][0/1] f[i][j][0/1]表示第 i i i小时,睡了 j j j小时,现在在/不在睡觉的最优解
第一遍:前天晚上没睡着
f [ i ] [ j ] [ 0 ] = max ⁡ ( f [ i − 1 ] [ j ] [ 0 ] , f [ i − 1 ] [ j ] [ 1 ] ) f [ i ] [ j ] [ 1 ] = max ⁡ ( f [ i − 1 ] [ j − 1 ] [ 0 ] , f [ i − 1 ] [ j − 1 ] [ 1 ] + u [ i ] ) \begin{aligned} &f[i][j][0]=\max(f[i-1][j][0],f[i-1][j][1])\\ &f[i][j][1]=\max(f[i-1][j-1][0],f[i-1][j-1][1]+u[i]) \end{aligned} f[i][j][0]=max(f[i1][j][0],f[i1][j][1])f[i][j][1]=max(f[i1][j1][0],f[i1][j1][1]+u[i])
边界为0
a n s 1 = max ⁡ ( f [ n ] [ b ] [ 0 ] , f [ n ] [ b ] [ 1 ] ) ans_1=\max(f[n][b][0],f[n][b][1]) ans1=max(f[n][b][0],f[n][b][1])

第二遍:前天晚上睡着了
f [ 1 ] [ 1 ] [ 1 ] = u [ 1 ] f[1][1][1]=u[1] f[1][1][1]=u[1]
再做一遍DP
a n s = max ⁡ ( a n s 1 , f [ n ] [ b ] [ 1 ] ) ans=\max(ans_1,f[n][b][1]) ans=max(ans1,f[n][b][1])

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int N=5e3+5;
int T,n,b,u[N],f[N][N][2],ans;

void DP(){
	for(int i=1;i<=n;++i)
		for(int j=1;j<=b;++j){
			f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);
			if(j!=1)
				f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+u[i]);
		}
	return;
}

void solve(){
	n=in,b=in;
	for(int i=1;i<=n;++i) u[i]=in;
	DP();
	ans=max(f[n][b][0],f[n][b][1]);
	f[1][1][1]=u[1];
	DP();
	ans=max(ans,f[n][b][1]);
	printf("%d\n",ans);
	return;
}

int main(){
	T=in;
	while(T--) solve();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问 12-6 用Timer类调度任务 12-7 练习 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值