一. 第二题
1.题面:
2.题解:
以为是01背包,测试样例正确但是段错误,
“但是这个题目没办法直接用动态规划,因为这个和会非常非常大,导致状态空间过大,会内存溢出,所以最后AC的代码还是用了搜索+剪枝,直接搜索所有可能的选择”
用·剪枝的dfs,回头补
补充:关于getline函数:
getline 的 C++ 函数。此函数可读取整行,包括前导和嵌入的空格,并将其存储在字符串对象中。
getline 函数如下所示:getline(cin, inputLine);
其中 cin 是正在读取的输入流,而 inputLine 是接收输入字符串的 string 变量的名称。
3.代码
int main()
{
string name;
string city;
cout << "Please enter your name: ";
getline(cin, name);
cout << "Enter the city you live in: ";
getline(cin, city);
cout << "Hello, " << name << endl;
cout << "You live in " << city << endl;
return 0;
}
段错误代码:QAQ
#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
long long int dp[400000],a[400000];
using namespace std;
int main(){
string s;
int n;
while(getline(cin,s)){
// cout<<s<<endl;
int i,j;
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
n=s.length();
long long int t=0;
j=0;
int flag=1;
long long int sum=0;
for(i=0;i<n;i++){
if(s[i]>='0'&&s[i]<='9'){
t=t*10+s[i]-'0';
}else if(s[i]==' '){
a[j]=t;
t=0;
sum+=a[j++];
}else{
flag=0;
break;
}
}
if(s[i-1]>='0'&&s[i-1]<='9'){
a[j]=t;
sum+=a[j++];
}
// for(i=0;i<n;i++){
// cout<<a[i]<<" ";
//
// }
// cout<<endl;
if(flag==0){
cout<<"ERROR"<<endl;
continue;
}else{
for(i=0;i<j;i++){
for(int v=sum/2;v>=a[i];v--){
dp[v]=max(dp[v],dp[v-a[i]]+a[i]);
}
}
int a=dp[sum/2],b=sum-dp[sum/2];
cout<<b<<" "<<a<<endl;
}
}
}
二.拦截导弹
1. 题面:
2. 题解:反过来求最长不降子序列
3.ac代码
#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
long long int dp[400000],a[400000];
using namespace std;
int main(){
int n,i,j;
while(cin>>n&&n){
for(i=0;i<n;i++){
cin>>a[i];
}
for(i=n-1;i>=0;i--){
dp[i]=1;
for(j=n-1;j>i;j--){
if(a[j]<=a[i])
dp[i]=max(dp[i],dp[j]+1);
}
}
int ans=0;
for(i=0;i<n;i++){
if(dp[i]>ans)
ans=dp[i];
}
cout<<ans<<endl;
}
}
三.合唱队形
1. 题面:
2.题解:
到第i位置时左边递增序列,右边递减序列的和最大,在求时第i位置被算了两次,所以要-1,n-(max-1)
3.ac代码
#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
int main(){
int n,i,j;
while(cin>>n&&n){
for(i=0;i<n;i++){
cin>>a[i];
}
for(i=n-1;i>=0;i--){
dp2[i]=1;
for(j=n-1;j>i;j--){
if(a[j]<a[i])
dp2[i]=max(dp2[i],dp2[j]+1);
}
}
for(i=0;i<n;i++){
dp1[i]=1;
for(j=0;j<i;j++){
if(a[j]<a[i])
dp1[i]=max(dp1[i],dp1[j]+1);
}
}
int ans=0;
for(i=0;i<n;i++){
if(dp1[i]+dp2[i]>ans)
ans=dp1[i]+dp2[i];
}
cout<<n-ans+1<<endl;
}
}