【DP】計劃11.8——(樹形依賴揹包總結)&&分數規劃思想
樹形依賴揹包指的就是一類具有樹形依賴關係的揹包問題。當選一個物品的前提是選另一件物品,而這些依賴關係構成了一個樹形關係。在容量有限的情況下,然後求最大的價值,這類問題我們就稱之為樹形依賴揹包。
樹形依賴揹包問題實際上是一類分組揹包問題,我們可以將每個點的子樹看成一個組,因為子樹內會選擇一定的點,但是選擇的點數只有一種情況,所以我們可以將子樹選擇()的情況看成一類物品,然後就做分組揹包即可。
我們設表示點,字數裡選了容量的最大價值,那麼則有DP方程:
for(int i=k;i>=w[x];i--) for(int j=0;j<=k;j++){ if(i+j>k) break; f[x][i+j]=max(f[x][i+j],f[x][i]+f[son][j]) }
一般的依賴關係會要求選擇當前子樹的樹根,因此初始狀態是f[x][w[x]]=v[x]
,並且在第一維列舉容量時只列舉到w[x]
。
還有一類DP方程,表示點字數內選擇了個點所獲得的最大的收益,那麼方程式也稍微變一下即可:
for(int i=siz[x];i>=1;i--)
for(int j=0;j<=siz[son];j++){
if(i+j>k) break;
f[x][i+j]=max(f[x][i+j],f[x][i]+f[son][j])
}
這類方程有一個很實用的優化,就是我們剛開始初始化siz[x]=1
,然後每次列舉完一個兒子的時候,就執行語句siz[x]+=siz[son]
。這樣可以大大降低複雜度,有巨佬指出,原來不進行優化的時間複雜度為,但是進行了這個陣列的優化後,可以接近於這也就是為什麼許多為的題目,也可以用樹形依賴揹包來做。
例題:
洛谷:P2014選課
題目描述
在大學裡每個學生,為了達到一定的學分,必須從很多課程裡選擇一些課程來學習,在課程裡有些課程必須在某些課程之前學習,如高等數學總是在其它課程之前學習。現在有N門功課,每門課有個學分,每門課有一門或沒有直接先修課(若課程a是課程b的先修課即只有學完了課程a,才能學習課程b)。一個學生要從這些課程裡選擇M門課程學習,問他能獲得的最大學分是多少?
輸入輸出格式
輸入格式:
第一行有兩個整數N,M用空格隔開。(1<=N<=300,1<=M<=300)
接下來的N行,第I+1行包含兩個整數ki和si, ki表示第I門課的直接先修課,si表示第I門課的學分。若ki=0表示沒有直接先修課(1<=ki<=N, 1<=si<=20)。
輸出格式:
只有一行,選M門課程的最大得分。
輸入輸出樣例
輸入樣例#1:
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
輸出樣例#1:
13
這道題就是最基本的樹形依賴揹包模板,就是上面說的第二類DP方程,甚至由於N的範圍很小,直接的DP也不會超時
程式碼中的方程式與上文所述的方程式效果相同,但是一般會選用上文的那種,因為那種方程式配合優化的時候複雜度更優
#include<bits/stdc++.h>
#define MAXN 205
using namespace std;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
int n,m,cnt,siz[MAXN],head[MAXN],nxt[MAXN],f[MAXN][105];
struct node{
int to,val;
}L[MAXN];
void add(int x,int y,int c){
L[cnt]=(node){y,c};
nxt[cnt]=head[x];head[x]=cnt;cnt++;
}
void get(int x){
siz[x]=1;
for(int i=head[x];i!=-1;i=nxt[i]){
int to=L[i].to;
get(to);siz[x]+=siz[to];
}
}
int dfs(int x){
for(int i=head[x];i!=-1;i=nxt[i]){
int to=L[i].to;dfs(to);
for(int j=siz[x]-1;j>=0;j--)
for(int k=0;k<=siz[to]-1;k++)
if(j>k) f[x][j]=max(f[x][j],f[x][j-k-1]+L[i].val+f[to][k]);
}
}
int main()
{
n=read();m=read();
memset(head,-1,sizeof(head));
memset(f,~0x3f,sizeof(f));
for(int i=1;i<=n;i++){
int x=read()+1,c=read();
add(x,i+1,c);
}
for(int i=1;i<=n+1;i++) f[i][0]=0;
get(1);dfs(1);
printf("%d",f[1][m]);
return 0;
}
洛谷:P1273有線電視網
題目要求不虧本的情況下最多的使用人數,我們採用第二種DP方式。最後的時候只要從大到小列舉,如果當前的大於等於0,那麼就是最多的使用人數。
#include<bits/stdc++.h>
#define MAXN 3005
using namespace std;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
int n,m,cnt,ans,head[MAXN],nxt[MAXN],go[MAXN],dp[MAXN][MAXN],w[MAXN],son[MAXN],siz[MAXN];
struct node{
int to,val;
}L[MAXN];
void add(int x,int y,int c){
L[cnt]=(node){y,c};
nxt[cnt]=head[x];head[x]=cnt;cnt++;
}
int dfs(int x){ //這個操作很silly,大家千萬不要學,又慢又長。直接在轉移時更新既短又快
siz[x]=1;
for(int i=head[x];i!=-1;i=nxt[i]){
int to=L[i].to;
siz[x]+=dfs(to);
}
return siz[x];
}
void calc(int x){
if(x>n-m){dp[x][1]=w[x];return;}
for(int i=head[x];i!=-1;i=nxt[i]){
int to=L[i].to;calc(to);
for(int j=siz[x];j>=0;j--)
for(int k=1;k<=siz[to];k++)
if(j>=k) dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[to][k]-L[i].val);
}
}
int main()
{
n=read();m=read();
memset(head,-1,sizeof(head));
memset(dp,~0x3f,sizeof(dp));
for(int i=1;i<=n;i++) dp[i][0]=0;
for(int i=1;i<=n-m;i++){
son[i]=read();
for(int j=1;j<=son[i];j++){
int x=read(),y=read();add(i,x,y);
}
}
for(int i=1;i<=m;i++) w[n-m+i]=read();
dfs(1);calc(1);
for(int i=0;i<=n;i++) if(dp[1][i]>=0) ans=i;
printf("%d",ans);
return 0;
}
Codeforces:815C
這道題用的是第二種方程,不同的是依賴關係只適用於優惠,因此即使我們要開兩個陣列,陣列記錄的是滿足依賴的能夠享受優惠的情況,陣列是不滿足依賴的情況,的轉移其實類似於,只是外層列舉容量那一維要倒著一直列舉到
#include<bits/stdc++.h>
#define MAXN 5005
#define ll long long
using namespace std;
ll read(){
char c;ll x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
ll n,m,ans,flag,v[MAXN],dc[MAXN],f[MAXN][MAXN],g[MAXN][MAXN];
ll cnt,head[MAXN<<1],nxt[MAXN<<1],go[MAXN<<1],siz[MAXN];
void add(ll x,ll y){
go[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;cnt++;
}
void dfs(ll x){
register int i,j,k;
g[x][0]=0;f[x][1]=v[x]-dc[x];g[x][1]=v[x];siz[x]=1;
for(k=head[x];k!=-1;k=nxt[k]){
ll to=go[k];dfs(to);
for(i=siz[x];i>=0;i--)
for(j=1;j<=siz[to];j++)
g[x][i+j]=min(g[x][i+j],g[x][i]+g[to][j]);
for(i=siz[x];i>=1;i--)
for(j=1;j<=siz[to];j++)
f[x][i+j]=min(f[x][i+j],f[x][i]+min(f[to][j],g[to][j]));
siz[x]+=siz[to];
}
}
int main()
{
n=read();m=read();register int i;
memset(head,-1,sizeof(head));
memset(f,127,sizeof(f));
memset(g,127,sizeof(g));
for(i=1;i<=n;i++){
v[i]=read();dc[i]=read();
if(i>1){ll x=read();add(x,i);}
}
dfs(1);
for(i=n;i;i--)
if(f[1][i]<=m||g[1][i]<=m){flag=1;printf("%d",i);break;}
if(!flag) puts("0");
return 0;
}
BZOJ:2427軟體安裝
Description
現在我們的手頭有N個軟體,對於一個軟體i,它要佔用Wi的磁碟空間,它的價值為Vi。我們希望從中選擇一些軟體安裝到一臺磁碟容量為M計算機上,使得這些軟體的價值儘可能大(即Vi的和最大)。
但是現在有個問題:軟體之間存在依賴關係,即軟體i只有在安裝了軟體j(包括軟體j的直接或間接依賴)的情況下才能正確工作(軟體i依賴軟體j)。幸運的是,一個軟體最多依賴另外一個軟體。如果一個軟體不能正常工作,那麼它能夠發揮的作用為0。
我們現在知道了軟體之間的依賴關係:軟體i依賴軟體Di。現在請你設計出一種方案,安裝價值儘量大的軟體。一個軟體只能被安裝一次,如果一個軟體沒有依賴則Di=0,這時只要這個軟體安裝了,它就能正常工作。
Input
第1行:N, M (0<=N<=100, 0<=M<=500)
第2行:W1, W2, … Wi, …, Wn (0<=Wi<=M )
第3行:V1, V2, …, Vi, …, Vn (0<=Vi<=1000 )
第4行:D1, D2, …, Di, …, Dn (0<=Di<=N, Di≠i )
Output
一個整數,代表最大價值。
Sample Input
3 10
5 5 6
2 3 4
0 1 1
Sample Output
5
這道題噁心的地方就在於整張圖可能是一個環,也可能是一個森林。
因此我們要先用縮點,將所有的環縮成一個點,這個點的,x是這個環中的點。這個也很好證明,因為形成了一個環形依賴,所以環中每個點都得同時選才行。
由於縮完點可能是森林,所以我們建一個虛點,並且,然後從開始轉移即可。
這道題運用的是上文的第一種DP方式,所以不存在優化,複雜度是跑不到上界的
#include<bits/stdc++.h>
#define MAXN 505
using namespace std;
int read(){
char c;int x=0,y=1;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
if(c=='-') y=-1;else x=c-'0';while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';return x*y;
}
int n,m,cnt,top,ans,w[MAXN],v[MAXN],head[MAXN<<1],nxt[MAXN<<1],go[MAXN<<1],in[MAXN];
int ta,co,dfn[MAXN],low[MAXN],vis[MAXN],sta[MAXN],col[MAXN],fa[MAXN],f[MAXN][505];
vector<int> g[MAXN];
struct node{
int w,v;
}F[MAXN];
void add(int x,int y){
go[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;cnt++;
}
void tarjan(int x){
dfn[x]=low[x]=++ta;
vis[x]=1;sta[++top]=x;
for(int i=head[x];i!=-1;i=nxt[i]){
int to=go[i];
if(!dfn[to]) tarjan(to),low[x]=min(low[x],low[to]);
else if(vis[to]) low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x]){
co++;int now=0;
while(now!=x){
now=sta[top--];
vis[now]=0;col[now]=co;
F[co].w+=w[now];
F[co].v+=v[now];
}
}
}
int find(int x){
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
void unionn(int x,int y){
x=find(x);y=find(y);
fa[y]=x;
}
void dfs(int x){
if(F[x].w>m) return;
f[x][F[x].w]=F[x].v;
for(int i=0;i<g[x].size();i++){
int to=g[x][i];
dfs(to);
for(int j=m;j>=F[x].w;j--)
for(int k=0;k<=m;k++){
if(j+k>m) break;
f[x][j+k]=max(f[x][j+k],f[x][j]+f[to][k]);
}
}
}
int main()
{
n=read();m=read();
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++) w[i]=read();
for(int i=1;i<=n;i++) v[i]=read();
for(int i=1;i<=n;i++){
int x=read();
if (x)add(x,i);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=co;i++) fa[i]=i;
for(int x=1;x<=n;x++)
for(int i=head[x];i!=-1;i=nxt[i]){
int to=go[i];
if(find(col[x])!=find(col[to])){
unionn(col[x],col[to]);in[col[to]]++;
g[col[x]].push_back(col[to]);
}
}
for(int i=1;i<=co;i++)
if(!in[i]) g[0].push_back(i);
F[0]=(node){0,0};
dfs(0);
for(int i=0;i<=m;i++) ans=max(ans,f[0][i]);
printf("%d",ans);
return 0;
}
BZOJ:4753最佳團體
Description
JSOI資訊學代表隊一共有N名候選人,這些候選人從1到N編號。方便起見,JYY的編號是0號。每個候選人都由一位
編號比他小的候選人Ri推薦。如果Ri=0則說明這個候選人是JYY自己看上的。為了保證團隊的和諧,JYY需要保證,
如果招募了候選人i,那麼候選人Ri"也一定需要在團隊中。當然了,JYY自己總是在團隊裡的。每一個候選人都有
一個戰鬥值Pi",也有一個招募費用Si"。JYY希望招募K個候選人(JYY自己不算),組成一個性價比最高的團隊。
也就是,這K個被JYY選擇的候選人的總戰鬥值與總招募總費用的比值最大。
Input
輸入一行包含兩個正整數K和N。
接下來N行,其中第i行包含3個整數Si,Pi,Ri表示候選人i的招募費用,戰鬥值和推薦人編號。
對於100%的資料滿足1≤K≤N≤2500,0<"Si,Pi"≤10^4,0≤Ri<i
Output
輸出一行一個實數,表示最佳比值。答案保留三位小數。
Sample Input
1 2
1000 1 0
1 1000 1
Sample Output
0.001
這道題需要結合分數規劃的知識,分數規劃指的是一類求最大值得問題,我們設,那麼,移項得,所以我們可以去二分列舉,然後依據這個大於的等式進行
對於這道題,我們去二分列舉最優值,將每個點的價值賦值為a[i]-x*b[i]
,然後進行樹形依賴揹包,求出選中個人之後的最大價值,如果最大價值大於,那麼也就是滿足條件。
#include<bits/stdc++.h>
#define MAXN 2550
#define db double
#define eps 1e-6
using namespace std;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
int n,k,cnt,a[MAXN],b[MAXN],siz[MAXN];
int head[MAXN<<1],nxt[MAXN<<1],go[MAXN<<1];
db l,r,mid,ans,v[MAXN],f[MAXN][MAXN];
void add(int x,int y){
go[cnt]=y;nxt[cnt]=head[x];head[x]=cnt;cnt++;
}
void dfs(int x){
f[x][1]=v[x];siz[x]=1;
for(int i=2;i<=k;i++) f[x][i]=-2147483647;
for(int i=head[x];i!=-1;i=nxt[i]){
int to=go[i];dfs(to);
for(int j=siz[x];j>=1;j--)
for(int p=0;p<=siz[to];p++){
if(j+p>k) break;
f[x][j+p]=max(f[x][j+p],f[x][j]+f[to][p]);
}
siz[x]+=siz[to];
}
}
int main()
{
k=read();n=read();k++;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++){
b[i]=read();a[i]=read();
int x=read();add(x,i);
}
l=0;r=1000000;
while(l<=r){
mid=(l+r)/2;
for(int i=1;i<=n;i++) v[i]=1.0*a[i]-mid*b[i];
dfs(0);
if(f[0][k]>=0) ans=mid,l=mid+eps;
else r=mid-eps;
}
printf("%.3f",ans);
return 0;
}
BZOJ:4033樹上染色
Description
有一棵點數為N的樹,樹邊有邊權。給你一個在0~N之內的正整數K,你要在這棵樹中選擇K個點,將其染成黑色,並將其他的N-K個點染成白色。將所有點染色後,你會獲得黑點兩兩之間的距離加上白點兩兩之間距離的和的收益。
問收益最大值是多少。
Input
第一行兩個整數N,K。
接下來N-1行每行三個正整數fr,to,dis,表示該樹中存在一條長度為dis的邊(fr,to)。
輸入保證所有點之間是聯通的。
N<=2000,0<=K<=N
Output
輸出一個正整數,表示收益的最大值。
Sample Input
5 2
1 2 3
1 5 1
2 3 1
2 4 2
Sample Output
17
【樣例解釋】
將點1,2染黑就能獲得最大收益。
這道題也算在樹形揹包的範疇裡,但是沒有依賴關係。我們設表示點,子樹裡染了了個黑點所能產生的貢獻。
這個定義的關鍵在於貢獻,因為子樹裡染了個黑點,產生的貢獻是與子樹外的點無關的(因為我們只靠慮當前的貢獻,後面的貢獻會在之後的計算中被統計)
我們思考如何統計這個貢獻,假設當前點為,它的一個兒子為,並且的子樹裡染了個黑點,那麼這個黑點在當前的貢獻就是
這個式子怎麼理解呢?就是兒子子樹中到兒子節點產生的貢獻,那麼加上從到的這條邊所()產生的貢獻,也就是到為止的貢獻。
如果子樹內有個黑點,那麼這個點總共會與外面的黑點形成個點對,每個點對都經過這條邊,所以是。那麼同理,白色的點會形成個點對,也就產生了的貢獻。
明白怎麼統計貢獻之後,就是簡單的樹形揹包了。依舊要使用優化,否則複雜度過不去。
#include<bits/stdc++.h>
#define MAXN 2005
#define ll long long
using namespace std;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
int n,m,cnt,head[MAXN<<1],nxt[MAXN<<1];
int siz[MAXN],fa[MAXN];
ll f[MAXN][MAXN];
struct node{
int to,val;
}L[MAXN<<1];
void add(int x,int y,int c){
L[cnt]=(node){y,c};
nxt[cnt]=head[x];head[x]=cnt;cnt++;
L[cnt]=(node){x,c};
nxt[cnt]=head[y];head[y]=cnt;cnt++;
}
void dp(int x,int fa){
siz[x]=1;
for(int i=head[x];i!=-1;i=nxt[i]){
int to=L[i].to;
if(to==fa) continue;dp(to,x);
for(int j=min(siz[x],m);j>=0;j--)
for(int k=min(siz[to],m);k>=0;k--){
f[x][j+k]=max(f[x][j+k],f[x][j]+f[to][k]+L[i].val*1ll*k*(m-k)+L[i].val*1ll*(siz[to]-k)*(n-m-(siz[to]-k)));
}
siz[x]+=siz[to];
}
}
int main()
{
n=read();m=read();
memset(head,-1,sizeof(head));
memset(f,-0x3f,sizeof(f));
for(int i=1;i<=n;i++) f[i][0]=f[i][1]=0;
for(int i=1;i<n;i++){
int x=read(),y=read(),c=read();
add(x,y,c);
}
dp(1,0);
printf("%lld",f[1][m]);
return 0;
}
相關推薦
【DP】計劃11.8——(樹形依賴揹包總結)&&分數規劃思想
樹形依賴揹包指的就是一類具有樹形依賴關係的揹包問題。當選一個物品的前提是選另一件物品,而這些依賴關係構成了一個樹形關係。在容量有限的情況下,然後求最大的價值,這類問題我們就稱之為樹形依賴揹包。 樹形依賴揹包問題實際上是一類分組揹包問題,我們可以將每個點的子樹看成
2018.11.08【CodeForces990】F. Flow Control(樹形DP)
傳送門 解析: 首先無解的情況當且僅當權值和不為0。 不然由於圖是聯通的,一定存在解,而實際上我們並不需要圖的性質,我們只需要樹的性質就可以做樹形DP了。 我們直接計算它子樹內部會有多少權值需要轉移,然後沿這條邊轉移就行了。 程式碼: #include&l
【HDU】1520 Anniversary party(樹形dp)
pre ret set rsa main eof hdu opened event 題目 題目 分析 帶權值的樹上最大獨立集 代碼 1 #include <bits/stdc++.h> 2 using nam
2018.12.08【BZOJ2152】聰聰可可(樹形DP)
傳送門 解析: 維護從子樹內到該節點上有多少條路徑模3餘0,1,2就行了。 統計考慮以每個點為 l c
【ARC101E】Ribbons on Tree(樹形DP,容斥原理)
Description 給定一棵點數為偶數的樹,要求有多少種將點兩兩配對的方案使得每一條邊至少被一對匹配點之間的最短路徑覆蓋。 Solution 根本想不到的DP系列。 首先考慮一個容斥
【DP】疊放箱子問題(兩種方法)
題目描述 某港口有一批集裝箱,將其編號,分別為1至N。每一個箱子的外型尺寸都是一樣的,現在要將其中某些集裝箱疊放起來,集裝箱疊放的規則如下: 1)每個集裝箱上最多隻能直接疊放一個集裝箱。 2)編號較小的集裝箱不能放在編號較大的集裝箱之上。 3)每個集裝箱都給出了自身的重量和可
【Luogu3398】倉鼠找sugar(樹鏈剖分)
name -m pac tor int modify 可能 iostream algorithm 【Luogu3398】倉鼠找sugar(樹鏈剖分) 題面 題目描述 小倉鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每個節點的編號為1~n。地下洞穴是一個樹形結構
【UVA】536 Tree Recovery(樹型結構基礎)
cnblogs using include http tree c++ code div str 題目 題目 ? ? 分析 莫名A了 ? ? 代碼 #include <bits/stdc++.h> using namespace std; string s1
【POJ2774】Long Long Message(後綴數組)
火車票 字符串 cat ios swa char 們的 same getc 【POJ2774】Long Long Message(後綴數組) 題面 Vjudge Description Little cat在Byterland的首都讀物理專業。這些天他收到了一條悲傷地信息:
【HDOJ】A Math Problem(對pow()的理解)
題意 hdu pan 打了 AC 輸入 show color 執行效率 A Math Problem http://acm.hdu.edu.cn/showproblem.php?pid=6182 題意:輸入一個n,問有多少個k的k次冪<=n(k=1,2,3...) 思
【BZOJ】2007: [Noi2010]海拔(平面圖轉對偶圖)
using targe line problem max 最小 mem AR pop 題目 傳送門:QWQ 分析 左上角是0,右下角是1。那麽大概整張圖是由0 1構成的。 那麽我們要找到0和1的分界線,值就是最小割。 然後變成求原圖最小割。 考慮
【P1330】封鎖陽光大學(圖論、BFS)
/* P1330 封鎖陽光大學 圖論 2018/11/22 */ #include<bits/stdc++.h> using namespace std; const int maxn=10010; vector<int>point[maxn];//STL
【模板】樹套樹(線段樹套Splay)
如題,這是一個模板。。。 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cctype> #defi
【Codeforces1073C】Vasya and Robot(二分+思維+字首和)
題目連結 C. Vasya and Robot time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output
【Java】圖形介面實踐(不斷更新中!)
建立一個簡單的窗體 package practice; import javax.swing.JButton; import javax.swing.JFrame; public class Test { public static void main(String[] args) {
【leetcode】兩數之和(C、Python解答)
題目: 給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。 你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。 示例: 給定 nums = [2, 7, 11, 15], target = 9 因為 nums[0] + nums[1] =
【HDU】1022Train Problem I(出棧可行問題)
題目大意:給出一個數(車的數目),兩個字串(前一個為現有車的排序,第二個為要組成的車的排序), Sample Input 3 123 321 3 123 312 Sample Output Yes. in in in out out out FINI
【 MATLAB 】prod 函式介紹(Product of array elements)
prod Product of array elements Syntax B = prod(A) B = prod(A,dim) B = prod(___,type) B = prod(___,nanflag) Description B = prod(A)
【數論】The Super Powers (英語+log函式使用)
題目連結: We all know the Super Powers of this world and how they manage to get advantages in political warfare or even in other sectors. B
【BZOJ1015】【JSOI2008】星球大戰Starwar(離線並差集)
傳送門 一道簡單題 所謂正難則反 我們考慮離線從後往前操作 就變成了每次加一個點求當前聯通塊個數 並查集就完了唄 程式碼稍微寫的有些繁瑣 但肯定還是可以看的 #include<bits/stdc++.h> using namespace std;