【编程练习2】
B 窗前的树
#include <iostream>
#define MAXSIZE 10005
using namespace std;
int main()
{
int L,M;
int t[MAXSIZE]={0};
while(cin>>L>>M)
{
int lo,hi;
while(M--)
{
cin>>lo>>hi;
for(int i=lo;i<=hi;i++)
t[i]=1;
}
int count=0;
for(int j=0;j<MAXSIZE;j++)
{
if(t[j]==1)count++;
}
cout<<L-count+1<<endl;
for(int k=0;k<MAXSIZE;k++)
{
t[k]=0;
}
}
return 0;
}
C 一个递归方程
(递归版)超时、超内存
#include <iostream>
using namespace std;
long f(int A,int B,int n)
{
//long f=1,g=1;//定义fun(0),和fun(1)
if (n==1||n==2)
{
return 1;
}
else return (A*f(A,B,n-1)+B*f(A,B,n-2))%7;
}
int main()
{
int A,B,n;
while((cin>>A>>B>>n)&&!(A==0&&B==0&&n==0))
{
for(int i=1;i<=n;i++)
cout<<"f("<<i<<")=\t\t\t"<<f(A,B,i)<<endl;
}
return 0;
}
(迭代版)
尝试用迭代代替递归,而最终理论和实践证明不可行
#include <iostream>
using namespace std;
__int64 f_I(int A,int B,int n)
{
__int64 f=1,g=1;//定义fun(0),和fun(1)
while(2<n--)
{
g=(A*g+B*f)%7;
f=((g+A*f)/B);
cout<<"g="<<g<<", f="<<f<<endl;
}
return g;
}
int main()
{
int A,B,n;
while((cin>>A>>B>>n)&&!(A==0&&B==0&&n==0))
{
if(n<=0)break;
for(int i=1;i<n;i++)
{cout<<"f("<<i<<")=\t\t\t"<<f_I(A,B,i)<<endl;}
}
return 0;
}
!(找规律)[
]
#include <iostream>
#define MSIZE 100
using namespace std;
int main()
{
int A,B,n,i;
int M[MSIZE];
M[1]=1;M[2]=1;
while((cin>>A>>B>>n)&&!(A==0&&B==0&&n==0))
{
//cout<<"M["<<1<<"]=\t\t\t"<<M[1]<<endl;
//cout<<"M["<<2<<"]=\t\t\t"<<M[2]<<endl;
for(i=3;i<MSIZE;i++)
{
M[i]=(A*M[i-1]+B*M[i-2])%7;
//cout<<"M["<<i<<"]=\t\t\t"<<M[i]<<endl;
if (M[i]==1&&M[i-1]==1)
{
break;
}
}
int index=n%(i-2);
if(index==0)cout<<M[i-2]<<endl;
else cout<<M[index]<<endl;
}
return 0;
}
最长字段和
(简易版)
#include <iostream>
#include <cstdio>
#include "maxsum.h"
#define MAXN 10001
#define GET_LEN(ARRAY,LEN) {LEN = (sizeof(ARRAY) / sizeof(ARRAY[0]));}
int a[MAXN];
int maxsum(int );
int maxsum(int ,int &a,int &b);
using namespace std;
int main()
{
int T,i;
cin>>T;
int n;
int lo=0,hi=0;
for(int k=1;k<=T;k++)
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
//cout<<maxsum(n)<<endl;
cout<<"Case "<<k<<":"<<endl;
cout<<maxsum(n,lo,hi)<<" "<<lo+1<<" "<<hi+1<<"\n\n";
for(i=0;i<n;i++)
{
a[i]=0;
}
lo=0,hi=0;
}
return 0;
}
int maxsum(int n,int &besti,int &bestj){
int sum=0;
int b=0;
int begin=0;
for(int i=0;i<=n;i++){
if(b>0)b+=a[i];
else {
b=a[i];
begin=i;
}
if(b>sum)
{
sum=b;
besti=begin;
bestj=i;
}
}
return sum;
}
/*
int maxsum(int n)
{
int ma=0;
int sum=0;
int lo,hi;
for(int i=0;i<=n;i++){
if(sum>0)
{
sum+=a[i];
}
else
{
sum=a[i];
}
if(sum>ma)
{
ma=sum;
}
}
return sum;
}*/
(动态规划版)
#include <iostream>
#include <cstdio>
//#include "maxsum.h"
#define MAXN 10001
#define GET_LEN(ARRAY,LEN) {LEN = (sizeof(ARRAY) / sizeof(ARRAY[0]));}
int a[MAXN];
int maxsum(int );
int maxsum(int ,int &a,int &b);
using namespace std;
int main()
{
int T,i;
cin>>T;
int n;
int lo=0,hi=0;
for(int k=1;k<=T;k++)
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
//cout<<maxsum(n)<<endl;
cout<<"Case "<<k<<":"<<endl;
cout<<maxsum(n,lo,hi)<<" ";cout<<lo+1<<" "<<hi+1<<"\n\n";
for(i=0;i<n;i++)
{
a[i]=0;
}
lo=0,hi=0;
}
return 0;
}
int maxsum(int n,int &besti,int &bestj){
int sum=0;
int b=0;
int begin=0;
for(int i=0;i<=n;i++){
if(b>0){b+=a[i];}
else {//b<=0
b=a[i];
if(b<0)
begin=i;
//cout<<"begin="<<begin<<", b="<<b<<endl;
}
if(b>sum)
{
sum=b;
besti=begin;
bestj=i;
//cout<<"lo="<<besti<<", hi="<<bestj<<endl;
}
}
return sum;
}
/*
int maxsum(int n)
{
int ma=0;
int sum=0;
int lo,hi;
for(int i=0;i<=n;i++){
if(sum>0)
{
sum+=a[i];
}
else
{
sum=a[i];
}
if(sum>ma)
{
ma=sum;
}
}
return sum;
}*/
(傻瓜都懂法)
#include <iostream>
using namespace std;
#define MAXN 100005
int main()
{
int T,n,i;
int a[MAXN],index[MAXN];
int max,lo,hi,ca;
cin>>T;
for(ca=1;ca<=T;ca++)
{
cin>>n;
for(i=1; i<=n; i++)
{
cin>>a[i];
index[i]=i;
}
max=a[1];
lo=1;
hi=1;
for(i=2; i<=n; i++)
{
if(a[i-1]>=0)
{
a[i]+=a[i-1];
index[i]=index[i-1];
}
if(a[i]>max)
{
max=a[i];
hi=i;
}
}
cout<<"Case "<<ca<<":"<<endl;
cout<<max<<" "<<index[hi]<<" "<<hi<<"\n\n";
}
return 0;
}
(AC)
#include <iostream>
#include <string.h>
#define MAXN 10005
#define GET_LEN(ARRAY,LEN) {LEN = (sizeof(ARRAY) / sizeof(ARRAY[0]));}
using namespace std;
char ch[MAXN];
int dp[MAXN];
int main()
{
int T;cin>>T;while(T--)
{
cin>>ch;
int len=strlen(ch);
//GET_LEN(ch,len)
//cout<<"len="<<len<<endl;
for(int i=0;i<len;i++){
dp[i]=1;//平凡的情况,最优解为1
}
for(int i=len-2;i>=0;i--){//定义两个游标i,j
for(int j=i+1;j<len;j++){
if(ch[i]>ch[j]&&dp[i]<dp[j]+1) //>表示降序,<表示升序
{
dp[i]=dp[j]+1;//每当遇见一个就加1
}
}
}
int max=0;
for(int k=0;k<len;k++)
{
if(max<dp[k])
{
max=dp[k];
}
}
cout<<max<<endl;
}
return 0;
}
E Card move
(AC)
#include <iostream>
#include <string.h>
#define MAXN 10005
#define GET_LEN(ARRAY,LEN) {LEN = (sizeof(ARRAY) / sizeof(ARRAY[0]));}
using namespace std;
int ch[MAXN];
int dp[MAXN];
int main()
{
int i,j,k;
int T;cin>>T;while(T--)
{
int len=0;
cin>>len;
for(i=0;i<len;i++)
cin>>ch[i];
//int len=strlen(ch);
//GET_LEN(ch,len)
//cout<<"len="<<len<<endl;
for(k=0;k<len;k++){
dp[k]=1;//平凡的情况,最优解为1
}
for(i=len-2;i>=0;i--){//定义两个游标i,j
for(j=i+1;j<len;j++){
if(!(ch[i]>ch[j])&&dp[i]<dp[j]+1) //>表示降序,<表示升序
{
dp[i]=dp[j]+1;//每当遇见一个就加1
}
}
}
int max=0;
for(k=0;k<len;k++)
{
//cout<<"dp["<<k<<"]="<<dp[k]<<endl;
if(max<dp[k])
{
max=dp[k];
}
}
//cout<<max<<endl;
//cout<<"move :"<<len-max<<" times"<<endl;
cout<<len-max<<endl;
}
return 0;
}
H
(动态规划后进行分割累加版) WA
#include <iostream>
#include <string.h>
#define MAXN 10005
#define GET_LEN(ARRAY,LEN) {LEN = (sizeof(ARRAY) / sizeof(ARRAY[0]));}
using namespace std;
long fun(int n)//求n的阶乘
{
long ans=1;
for(int i=1;i<=n;i++)
ans*=i;
cout<<n<<"的阶乘为"<<ans<<endl;
return ans;
}
long fun(int hi,int lo)
{
long ans=1;
for(int i=hi;i>=lo+1;i--)
ans*=i;
cout<<hi<<"中取"<<lo<<"的排列为"<<ans<<endl;
return ans;
}
long per(int m,int n)//求m个元素中取n个的组合数
{
long ans=0;
if(m>=n){
if(m==n)return 1;
if(n==1||n==(m-1)) return m;
if(n==2||(n==(m-2)))return m*(m-1)/2;
ans=fun(m,n)/fun(m-n);
cout<<"select "<<n<<" from "<<m<<" have "<<ans<<" measures"<<endl;
}
return ans;
}
int ch[MAXN];
int dp[MAXN];
int main()
{
int i,j,k,l,r;
// cin>>i>>j;cout<<per(i,j)<<endl;
int T;cin>>T;
while(T--)
{
int len=0;
cin>>len;
int m=0;cin>>m;
for(i=0;i<len;i++)
cin>>ch[i];
//int len=strlen(ch);
//GET_LEN(ch,len)
//cout<<"len="<<len<<endl;
for(k=0;k<len;k++){
dp[k]=1;//平凡的情况,最优解为1
}
for(i=len-2;i>=0;i--){//定义两个游标i,j
for(j=i+1;j<len;j++){
if(ch[i]<ch[j]&&dp[i]<dp[j]+1) //>表示降序,<表示升序
{
dp[i]=dp[j]+1;//每当遇见一个就加1
}
}
}
int max=0;
for(k=0;k<len;k++)
{
//cout<<"dp["<<k<<"]="<<dp[k]<<endl;
if(max<dp[k])
{
max=dp[k];
}
}
//cout<<max<<endl;
int sum=0;
if (m==1){
sum=len;
}
else{
for(l=len-2,r=len-1;l>=0;l--,r--)
{
if(dp[l]<dp[r])//出现节点
{
if (dp[r]>=m)
{
sum+=per(dp[r],m);
//cout<<"sum="<<sum<<endl;
}
}
if(l==0)
{
if (dp[l]>=m){
sum+=per(dp[l],m);
//cout<<"sum="<<sum<<endl;
}
}
}
}
//cout<<"final="<<sum<<endl;
cout<<sum<<endl;
//cout<<"move :"<<len-max<<" times"<<endl;
//cout<<len-max<<endl;
}
return 0;
}