グッズコレクション
バイナリの答え。複雑\(O(N \ N-ログ)\) 。
貨物のグループ化
では、事前に計算コストのアイデア、何が起こるかをインストールするために、新たな貨物ボックスを考えます。
明らかにコストが背後にあるすべての商品の合計重量に加算されます。
(\ 60 \)分\(O(N-2 ^)\) DPコード:
#include<bits/stdc++.h>
#define LL long long
const int SIZE=100005,INF=0x3F3F3F3F;
int n;
LL W,A[SIZE],sum[SIZE];
LL DP[SIZE];
using std::max;
using std::min;
struct Seg_Tree
{
#define LC(x) (x<<1)
#define RC(x) (x<<1|1)
#define Mid ((L+R)>>1)
LL Max[SIZE*4],Min[SIZE*4];
void push_up(int x)
{
Max[x]=max(Max[LC(x)],Max[RC(x)]);
Min[x]=min(Min[LC(x)],Min[RC(x)]);
}
void Build(int x,int L,int R)
{
if(L==R){Max[x]=Min[x]=A[L];return;}
Build(LC(x),L,Mid);
Build(RC(x),Mid+1,R);
push_up(x);
}
LL Query_Max(int x,int L,int R,int X,int Y)
{
if(L>Y||R<X)return -INF;
if(L>=X&&R<=Y)return Max[x];
return max(Query_Max(LC(x),L,Mid,X,Y),Query_Max(RC(x),Mid+1,R,X,Y));
}
LL Query_Min(int x,int L,int R,int X,int Y)
{
if(L>Y||R<X)return INF;
if(L>=X&&R<=Y)return Min[x];
return min(Query_Min(LC(x),L,Mid,X,Y),Query_Min(RC(x),Mid+1,R,X,Y));
}
}T;
int main()
{
scanf("%d%lld",&n,&W);
for(int i=1;i<=n;i++)
{
scanf("%lld",&A[i]);
sum[i]=sum[i-1]+A[i];
}
T.Build(1,1,n);
memset(DP,0x3F,sizeof(DP));
DP[0]=0;
for(int i=1;i<=n;i++)
for(int k=i-1;k>=0&&sum[i]-sum[k]<=W;k--)
DP[i]=min(DP[i],DP[k]+sum[n]-sum[k]+T.Query_Max(1,1,n,k+1,i)-T.Query_Min(1,1,n,k+1,i));
printf("%lld",DP[n]);
return 0;
}
地形・コンピューティング
日常的な質問は、私はあまりにも料理だったので。グラフ3員環/ 4元、それを有向非巡回するだけでなく、3/4員環のために学ぶこと。
[ご注意] && 3員環、4員環カウント - LuitaryiJackパークのブログを
統計3/4員環の主なアイデアはある中東でに出会い、つまり、二つの部分にリング分割を置く。スタートポイントマークから、リングの半分、そして一致させようとし、残りの半分を。あなたが合うようにしようとする過程で発生した場合マークされたポイントに、二つの半分は、リングを構成することができます。
(ここでBGMべきである中東で)
このような観点が、時間複雑である\(O(N ^ 2) \) が、特定の順序では、リングが来る、時間複雑さを低減することができる場合に\(O(M \ SQRT { M})\) 。
私たちは、次の規則に従ってすべてのランキングポイントを与えることができます。
- ノードの大程度の前面に小さな程度ノード。
- 同じノード次数、小さな頂面の数。
次いで、無指向性エッジのそれぞれについて。
- あなたは、3員環、見つけた場合はランクからさらに小さく、大きな順位のを。
- あなたは、4員環を探している場合でも、小さなのランクから大きな順位に。
最後に、統計への答えは、上記の監督規則に従って、各リングは一度だけカウントされます。
3員環を探している場合は、すべてのために\(U \) 、それはマークポイント\(V \) 。次に列挙ポイント\(V \) 、その後、列挙\(Vは\)ポイントです\ (W \)場合、\(Wを\)標識されている、\((U、V、W )\) 3員環を形成します。
探している場合、各点について、リング4つ員\(U \) 、列挙画像における\(U \)点である\(V \) 、次に列挙有向グラフにおける\(Vは\)に点\(W \) 。タグ\(W \) 。再び列挙画像における\(Uは\)点である\(V \) 、列挙有向グラフにおける\(V \)点である\ (W \) 、場合\(W \)が標識されている、(形成されている可能性が1つ以下の 4員環)。交換「画像」と「有向グラフ」列挙順序が可能であるが、各ことを確実にするために4員環は、一度だけカウントされ、上記動作が必ずしも必要
Rank[w]>Rank[u]
。
この問題は、アルゴリズムの性質が変化しない、4員環合計に4員環を数えるが、時に「マーク」と重みの数を変更することができます。
#include<bits/stdc++.h>
using namespace std;
const int SIZE=100005,Mod=1e9+7;
#define LL long long
#define pb push_back
LL A[SIZE];
int n,m,Deg[SIZE],ID[SIZE],Rnk[SIZE],Cnt[SIZE];
LL Ans,C[SIZE];
vector<int>G1[SIZE],G2[SIZE];
bool cmp(int A,int B)
{
return Deg[A]==Deg[B]?A<B:Deg[A]<Deg[B];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&A[i]);
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
G1[u].pb(v);
G1[v].pb(u);
}
for(int i=1;i<=n;i++)
{
ID[i]=i;
Deg[i]=G1[i].size();
}
sort(ID+1,ID+1+n,cmp);
for(int i=1;i<=n;i++)
Rnk[ID[i]]=i;
for(int u=1;u<=n;u++)
for(int v:G1[u])
if(Rnk[v]>Rnk[u])
G2[u].pb(v);
for(int u=1;u<=n;u++)
{
for(int v:G1[u])
for(int w:G2[v])
if(Rnk[w]>Rnk[u])
{
Ans=(Ans+C[w]+1LL*Cnt[w]*A[v])%Mod;
C[w]=(C[w]+A[u]+A[w]+A[v])%Mod;
++Cnt[w];
}
for(int v:G1[u])
for(int w:G2[v])
if(Rnk[w]>Rnk[u])
{
C[w]=0;
Cnt[w]=0;
}
}
printf("%lld",Ans);
return 0;
}