得分
ABD
得分20
正确
C
得分0
不会
E
最短路径模板
F
得分15
G
得分15*0.5=7.5
之前写的代码:
#include<iostream>
#include <stack>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=110;
const long long M=1e8;
int n;
int w[N];
int A[M];//标记哪些球用过了
int sum=0;
stack <int> s1;
stack <int> s2;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>w[i];
sum+=w[i];
}
s1.push(w[1]);
A[w[1]]++;
for(int i=2;i<=n;i++){
s2=s1;
while(!s1.empty()){
int t=s1.top();
s1.pop();
int a1=t+w[i];
int a2=abs(t-w[i]);
s2.push(a1);
s2.push(a2);
A[a1]++;
A[a2]++;
}
s1=s2;
while(!s2.empty())
s2.pop();
s1.push(w[i]);
A[w[i]]++;
}
int ans=0;
for(int i=1;i<=sum;i++)
if(A[i]!=0)
ans++;
cout<<ans;
return 0;
}
看了题解之后,和我想的思路好像一样。不过我的思路因为不断push元素到栈里,最终内存超了,这里用dp数组很好
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int n;
int a[N];
int dp[N][110000];
//考虑到每一次可以只添加一个砝码进来,这也是蓝桥杯中常有的背包思想
//这样的话,每次添加一个砝码后的种类就只和之前状态有关了
//定义dp[i][j]为添加了i个砝码后,某种重量j是否存在,存在为1,不存在为0
int main(){
cin>>n;
int sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
dp[1][a[1]]=1;//初始化
//从第二个开始
for(int i=2;i<=n;i++){
for(int j=1;j<=sum;j++)
dp[i][j]=dp[i-1][j];//将上一个状态的复制过来
dp[i][a[i]]=1;//需要把当前值加上去
for(int k=1;k<=sum;k++){
if(dp[i-1][k]){//注意这里是i-1,因为判断的是上一个状态
dp[i][k+a[i]]=1;
dp[i][abs(k-a[i])]=1;
}
}
}
int ans=0;
for(int i=1;i<=sum;i++)
if(dp[n][i])
ans++;
cout<<ans;
return 0;
}
H
得分20*0.4=8
I
得分25*0.6=15