社区讨论

一个问题

学术版参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mi7cz090
此快照首次捕获于
2025/11/20 19:39
4 个月前
此快照最后确认于
2025/11/20 19:39
4 个月前
查看原帖
TG D1T2我搜索的时候开了一个f[x][num]来记忆化,表示到第x个结果为num是否曾经访问过,如果f[x][num]==true,就return掉,如果是false就继续,但是我f开200乘25000和开200乘250000的数组分数不一样,为什么呢
CPP
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxN=200,maxL=25000 + 100;
int t;
int n,a[maxN+1];
bool f[maxN+1][maxL+1],vis[maxL+1];
bool flag[maxN+1];
inline int read()
{
    int num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) num=(num<<3)+(num<<1)+(ch^48),ch=getchar();
    return num*f;
}
inline void dfs1(int x,int sum,int loc)
{
    if(f[x][sum]) return;
    if(sum<=maxL) f[x][sum]=true;
    vis[sum]=true;
    if(x>n/2) return;
    if(x==loc) {dfs1(x+1,sum,loc); return;}
    for(int i=0;sum+i*a[x]<=a[loc];i++) dfs1(x+1,sum+i*a[x],loc); 
}
inline void dfs2(int x,int sum,int loc)
{
    if(flag[loc]) return;
    if(sum<=maxL&&f[x][sum]) return;
    if(sum<=maxL) f[x][sum]=true;
    if(a[loc]-sum>=0&&a[loc]-sum<=maxL&&vis[a[loc]-sum]) {flag[loc]=true; return;}
    if(x>n) return;
    if(x==loc) {dfs2(x+1,sum,loc); return;}
    for(int i=0;sum+i*a[x]<=a[loc];i++) dfs2(x+1,sum+i*a[x],loc); 
}
int main()
{
    t=read();
    while(t--)
    {
        memset(flag,false,sizeof(flag));
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++)
        {
            memset(f,false,sizeof(f));
            memset(vis,false,sizeof(vis));
            dfs1(1,0,i);
            memset(f,false,sizeof(f));
            dfs2(n/2+1,0,i);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
          if(!flag[i]) ans++;
        printf("%d\n",ans);
    }
    return 0;
 } 

回复

0 条回复,欢迎继续交流。

正在加载回复...