焦作網路賽(今天開始ACM康復計劃~)
阿新 • • 發佈:2018-12-10
題目在計蒜課上
K:Transport Ship
給n種船,每個船分別可以裝2^n-1個貨物,有S個貨物,問裝S個貨物就幾種裝配方法。
開始想的多元線性迴歸,然後想的暴力,腦子真的蠢,這麼裸的揹包沒一眼看出,補補補補補補補補!!
程式碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const long long maxn = 1e5+7; const int mod=1e9+7; struct ttt{ int v,num; }; ttt q1[maxn]; int res[maxn]; int main(){ //freopen("in.txt","r",stdin); //freopen("out1.txt","w",stdout); int i,j,k,f1,f2,f3,t1,t2,t3; int T; int n,m; int l; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); memset(res,0,sizeof(res)); for(i=1;i<=n;i++){ scanf("%d %d",&q1[i].v,&q1[i].num); } res[0]=1; for(i=1;i<=n;i++){ for(j=0;j<q1[i].num;j++){ //因為是2^k-1個,所以取的時候是1/2/4/8/2^(k-1)剛好全部覆蓋 for(k=10000;k>=q1[i].v;k--){ if(k-(1<<j)*q1[i].v<0)break; res[k]+=res[k-(1<<j)*q1[i].v]; res[k]%=mod; } } } for(i=1;i<=m;i++){ scanf("%d",&t1); // cout << t1<< endl; printf("%d\n",res[t1]); } } return 0; }
L:矩陣快速冪(從黃大佬手裡摸了一套超短的快速冪板子
自己找一個遞推公式。
本來一般矩陣快速冪是f[n]=2f[n-1]+3f[n-2]+5f[n-5]的形式,
現在改為f[n]=2g(n-1)+h(n-1)
但是每個g和h又能通過前面的函式推出,那麼這樣子也可以矩陣快速冪列出矩陣
#include<bits/stdc++.h> using namespace std; typedef long long ll; const long long maxn = 1e5+7; const int mod=1e9+7; const int N = 9; struct Mat{ ll m[N][N]; void clear(){memset(m,0,sizeof(m));} void I(){for (int i=0;i<N;i++) m[i][i]=1;} }; Mat mul(const Mat &a, const Mat &b){ Mat c;c.clear(); for (int i=0;i<N;i++) for (int j=0;j<N;j++){ for (int k=0;k<N;k++) c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod; c.m[i][j]%=mod; } return c; } Mat qpow(Mat a, ll x){ //這裡注意傳進來的引數要為long long 不然會報超時 Mat ans; ans.clear(); ans.I(); for (;x;a=mul(a,a),x>>=1) if (x&1) ans=mul(ans,a); return ans; } Mat t2=(Mat){{ {0,0,0,1,0,0,1,0,0}, {1,0,0,1,0,0,1,0,0}, {1,0,0,1,0,0,0,0,0}, {0,1,0,0,1,0,0,1,0}, {0,1,0,0,0,0,0,1,0}, {0,1,0,0,1,0,0,0,0}, {0,0,1,0,0,0,0,0,1}, {0,0,0,0,0,1,0,0,1}, {0,0,1,0,0,1,0,0,0} }}; int main(){ //freopen("in.txt","r",stdin); //freopen("out1.txt","w",stdout); int i,j,k,f1,f2,f3; int T; int l; ll t1; scanf("%d",&T); while(T--){ scanf("%lld",&t1); if(t1==1){ printf("3\n");continue; }else if(t1==2){ printf("9\n");continue; } Mat t3; t3=qpow(t2,t1-2); int ans=0; for(i=0;i<9;i++) for(j=0;j<9;j++){ ans+=t3.m[i][j]; ans%=mod; } printf("%d\n",ans); } return 0; }