P1036

· · 个人记录

一、分析题目

审题很重要,它决定着你是否能通过题目。

题目中说什么?我们要关注

(1)哪些变量?

n(表示有几个数)

k(表示用几个数)

n个数(分别是哪些数)

(2)要求的是什么?

计算出和为素数(质数)的共有多少种。

(3)看懂样例了吗?

题目中有写。

(4)有思路了吗?

这得问大家。

二、解决算法

思路如何?算法有了吗?也是一个不可缺少的部分。

一、穷举

当然是穷举。这道题肯定不能用动规(Dynamic Planning)。可是,你知道穷举几重循环吗?k重。不知道k是几怎么办?穷举!1重、2重……20重。六六六啊!

二、贪心

Tan what?Can you give me an answer?

三、深搜

刚才说到穷举,深搜不是吗?都属于暴力。

据我所知:

深搜=n重循环

有了算法,进入

三、彻底解决

接下来该怎么做呢?

首先,深度深度,函数里有一个表示深度的参数——

dep

其次,求和求和,函数里有一个表示和的参数——

sum

接着,函数里得有一个做到(数组的)哪儿的参数——

wts

很好!

DFS经典套路如下:

数据类型 dfs(参数){
    if(到达数据极限){
        极限语句;
    }
    else{
        for(int i=1;i<=n;i++){
            if(来访过)continue;
            else{
                标记成来访过;
                dfs(参数);
                标记成未来访过;
            }
        }
    }
}

套公式的话如下(只填if):

if(dep==k){
    if(prime(sum))ans++;
}

标准代码

想想就觉得激动呢!
#include<bits/stdc++.h>
using namespace std;
int n,k,a[25];
long long tot=0;
bool vis[25];
bool p(int x){
    if(x<2)return 0;
    if(x==2)return 1;
    if(x%2==0)return 0;
    for(int i=3;i*i<=x;i+=2){
        if(x%i==0)return 0;
    }
    return 1;
}
void dfs(int dep,int sum,int wts){
    if(dep==k){
        if(p(sum))tot++;
        return;
    }
    for(int i=wts;i<n;i++){
        //???
    }
    return;
}
int main(){
    cin>>n>>k;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    dfs(0,0,0);
    cout<<tot<<endl;
}

蟹蟹!