题目在计蒜课上
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;
}