C题
dp大法好
没考虑太多
- 存储
代表第
人
代表第
个棋子
- 开了
(1-N)表示在前
个棋子里面选
(0-15)表示四位二进制数,比如“1101”代表一、二、四号选了棋子,三号还没选棋子
至此我们可以推出 比如当
总结下规律,简化代码,可以得到
dp[i][j]=dp[i-1][j];
ll t=0,m=j;
while(m>0){
if(m%2==1){
ll p=pow(2,t);
dp[i][j]+=dp[i-1][j-p]*a[4-t][i];
}
t++;m/=2;
}附上全部代码
#include<stdio.h>
#include<iostream>
#include <stdlib.h>
#include <time.h>
#include<string.h>
#include<math.h>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<algorithm>
#define ll long long
#define maxn 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define mdd 1000000007
#include <fstream>
using namespace std;
ll i,j,m,n,x,y,z,l,r,t,k,p,pp,num,sum,cnt,flag,minn,maxx,ans,key;
ll a[20][20100],b[200100],mapp[200][200],vis[1010][200],pre[100100],dp[20100][20];
char cc[60],zz;
//double xa[5],ya[5],xb[5],yb[5],ee,ff;
//vector<string>v;
//string a,b;
//map<string,map<string,ll>>mp;
priority_queue<ll,vector<ll>,greater<ll> >s;
struct qq{ll xx,yy,zz,dd;};
bool cmp(qq u,qq v){
return u.xx<v.xx;
}
void f(ll i,ll j){
dp[i][j]=dp[i-1][j];
ll t=0,m=j;
while(m>0){
if(m%2==1){
ll p=pow(2,t);
dp[i][j]+=dp[i-1][j-p]*a[4-t][i];
}
t++;m/=2;
}
}
int main(){
scanf("%lld",&n);
for(i=1;i<=4;i++){
for(j=1;j<=n;j++)scanf("%1lld",&a[i][j]);
}
for(i=0;i<=n;i++)dp[i][0]=1;
for(i=1;i<=n;i++){
for(j=1;j<=15;j++){
f(i,j);
}
}
printf("%lld\n",dp[n][15]);
}
小菜鸡一枚,欢迎纠正~

京公网安备 11010502036488号