Algorithm 子序列和
考虑第一个整数是A,A[i]等于A的第i位(从右到左基于0的索引),第二个整数是B,B[i]等于B的第i位(从右到左基于0的索引) A和B的幸运和等于C,C[i]=max(A[i],B[i])。如果i大于或等于整数的大小,则第i位等于0 比如说,Algorithm 子序列和,algorithm,Algorithm,考虑第一个整数是A,A[i]等于A的第i位(从右到左基于0的索引),第二个整数是B,B[i]等于B的第i位(从右到左基于0的索引) A和B的幸运和等于C,C[i]=max(A[i],B[i])。如果i大于或等于整数的大小,则第i位等于0 比如说, 47和729的幸运之和是 类似地,W的幸运和=(74,92,477) 那是 所以w的幸运和等于497 任务:我们得到一个数组W,其中包含n(1,因为答案的每一位都是独立的。所以分别更新它们,整个算法需要O(n*log10(W)) 以下是我刚刚编写的
任务:我们得到一个数组W,其中包含n(1,因为答案的每一位都是独立的。所以分别更新它们,整个算法需要
O(n*log10(W))
以下是我刚刚编写的代码:
#包括
#包括
#包括
#定义最大值15
使用名称空间std;
int n;
int-ans[MAXL];
int main(){
int i,j,w;
scanf(“%d”和“&n”);
memset(ans,0,sizeof(ans));
而(n--){
扫描频率(“%d”和“w”);
i=0;
而(w>0){
j=w%10;
ans[i]=max(ans[i],j);
i++;
w/=10;
}
}
布尔标志=假;
对于(i=MAXL-1;i>=0;i--){
如果(ans[i]>0)标志=true;
如果(标志)printf(“%d”,ans[i]);
}
printf(“\n”);
返回0;
}
因为答案的每一位都是独立的。所以分别更新它们,整个算法需要O(n*log10(w))
以下是我刚刚编写的代码:
#包括
#包括
#包括
#定义最大值15
使用名称空间std;
int n;
int-ans[MAXL];
int main(){
int i,j,w;
scanf(“%d”和“&n”);
memset(ans,0,sizeof(ans));
而(n--){
扫描频率(“%d”和“w”);
i=0;
而(w>0){
j=w%10;
ans[i]=max(ans[i],j);
i++;
w/=10;
}
}
布尔标志=假;
对于(i=MAXL-1;i>=0;i--){
如果(ans[i]>0)标志=true;
如果(标志)printf(“%d”,ans[i]);
}
printf(“\n”);
返回0;
}
以下是我能想到的(尚未完成):
将DP与位掩码一起使用。我们现在用以下方式表示一个数字:每个位分为五类:
5^8
因此,我们让f[i][s]
表示我们可以从第一个i数字
中选择子集的总方式,以确定位掩码为s的数字
这是我刚刚再次编写的代码……
还有三件事:
使用\uuu int64
或long
而不是int
来表示f[][]
使用queue
加速枚举,因为如果我们使用枚举(i=0;i
,则存在许多不可能的状态(即f[][s]==0)
使用f[0..1][MAXS]可降低内存成本
示例代码:
#包括
#包括
#包括
#包括
#定义MAXN 51
#定义MAXS 390625//5^8
使用名称空间std;
const int exp[]={1,5,25,125,625,3125,15625,78125,390625};
int n;
int w[MAXN];
结构节点{
int i;
int stat;
节点(intx,inty):i(x),stat(y){
};
队列q;
__int64 f[MAXN][MAXS];
boolinq[MAXN][MAXS];
int main(){
//freopen(“test.txt”、“r”、stdin);
memset(f,0,sizeof(f));
memset(inq,0,sizeof(inq));
scanf(“%d”和“&n”);
对于(inti=0;i0){
f[i+1][j]+=f[i][j];
int stat=j;
int loc=0;
int k=0;
对于(int p=w[i];p>0;p/=10){
k=p%10;
如果(k以下是我能想到的(尚未完成):
将DP与位掩码一起使用。我们现在用以下方式表示一个数字:每个位分为五类:
(0)->0
(1,2,3)->1
(4) ->2
(5,6)->3
(7) ->4
(8,9)->-1
正如我们很容易看到的,每当一个位是8或9时,它就永远不能被添加到一个有效的解决方案中。现在我们用位掩码来表示这个数字,它需要5^8
因此,我们让f[i][s]
表示我们可以从第一个i数字
中选择子集的总方式,以确定位掩码为s的数字
这是我刚刚再次编写的代码……
还有三件事:
使用\uuu int64
或long
而不是int
来表示f[][]
使用queue
加速枚举,因为如果我们使用枚举(i=0;i
,则存在许多不可能的状态(即f[][s]==0)
使用f[0..1][MAXS]可降低内存成本
示例代码:
#包括
#包括
#包括
#包括
#定义MAXN 51
#定义MAXS 390625//5^8
使用名称空间std;
const int exp[]={1,5,25,125,625,3125,15625,78125,390625};
int n;
int w[MAXN];
结构节点{
int i;
int stat;
节点(intx,inty):i(x),stat(y){
};
队列q;
__int64 f[MAXN][MAXS];
boolinq[MAXN][MAXS];
int main(){
//freopen(“test.txt”、“r”、stdin);
memset(f,0,sizeof(f));
memset(inq,0,sizeof(inq));
scanf(“%d”和“&n”);
对于(inti=0;i0){
f[i+1][j]+=f[i][j];
int stat=j;
int loc=0;
max(7,9)=9
max(4,2)=4
max(0,7)=7
answer = 749
max(4,2) = 4
max(7,9) = 9
Lucky sum of 74,92 = 94
Lucky sum of W=(Lucky sum of (94,477))
max(4,7)=7
max(9,7)=9
max(0,4)=4