#include
using namespace std;
int n,m,num,ans,p;
string s[100010];
bool f[100010];
int main(){
//freopen("toy.in","r",stdin);
// freopen("toy.out","w",stdout);
cin>>n>>m;
for(int i=0;i>f[i]>>s[i];
while(m--){
cin>>p>>num;
if (p==f[ans]) ans-=num;
else ans+=num;
if (ans<0) ans+=n;
else if (ans>=n) ans-=n;
}
cout<
T2 天天爱跑步
玄学数链剖分,学了来贴代码。
T3 换教室
比较容易想的dp,建个三位数组,状态的话第一维存上课时间,第二维存当前教室,第三维0 1表示当前教室是否申请,转移就四种情况,一种是上个教室不申请,这个教室申请,一种是上个教室不申请,这个教室申请,一种是上个教室和这个教室都申请,最后是两个教室都不申请。前两种都只有两种可能性,因为申请成功和不成功是独立事件,所以成功和不成功是对立事件,所以可以直接用1减去申请成功的可能性。而都申请的情况下,有四种可能性,分别列出来(很恶心),都不申请的情况就只有一种可能性。然后因为数据比较小,直接可以用Floyd处理最短路,注意dp数组的初始化,最后求出最小值。
#include
using namespace std;
int n,m,v,e,x,y,z;
int c[2010],d[2010],f[310][310];
double k[2010],dp[2010][2010][2],ans=1e9;
int main(){
freopen("classroom.in","r",stdin);
freopen("classroom.out","w",stdout);
cin>>n>>m>>v>>e;
memset(f,0x3f3f3f,sizeof(f));
for(int i=1;i<=n;++i){
cin>>c[i];
}
for(int i=1;i<=n;++i){
cin>>d[i];
}
for(int i=1;i<=n;++i){
cin>>k[i];
}
for(int i=0;i<=n;++i)
for(int j=0;j<=n;++j)
for(int k=0;k<=1;++k){
dp[i][j][k]=1e9;
}
dp[0][0][0]=0;
for(int i=1;i<=e;++i){
cin>>x>>y>>z;
if(f[x][y]>z) f[y][x]=f[x][y]=z;
}
for(int i=1;i<=v;i++){
f[i][i]=f[i][0]=f[0][i]=0;
}
f[0][0]=0;
for(int x=1;x<=v;++x)
for(int i=1;i<=v;++i)
for(int j=1;j<=v;++j){
f[i][j]=f[j][i]=min(f[i][j],f[i][x]+f[j][x]);
}
/* for(int i=1;i<=v;i++){
for(int j=1;j<=v;++j)
printf("%d ",f[i][j]);
cout<1){
dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][1]+f[c[i-1]][c[i]]*(1-k[i-1])*(1-k[i])+f[d[i-1]][d[i]]*k[i-1]*k[i]+f[c[i-1]][d[i]]*(1-k[i-1])*k[i]+f[d[i-1]][c[i]]*(1-k[i])*k[i-1]);
}//上个选这个也选
if(j)
dp[i][j][0]=min(dp[i-1][j][0]+f[c[i-1]][c[i]],dp[i-1][j][1]+f[c[i-1]][c[i]]*(1-k[i-1])+f[d[i-1]][c[i]]*k[i-1]);//这个教室不选上个选
else dp[i][j][0]=dp[i-1][j][0]+f[c[i-1]][c[i]];//没得选 安排
}
for(int i=0;i<=n;++i){ ans=min(ans,min(dp[n][i][0],dp[n][i][1]));
}
printf("%.2lf\n",ans);
}
又是编译错误。。。。这两天真的是,下次我再打错freopen我是狗,很蠢啊两次200+都直接水爆,交之前一定要检查输入输出文件!!!
T1 组合数问题
简单数论,手推之后发现是个杨辉三角,然后试了几个数据发现不对,查了发现边界都是0,所以只需要注意单独处理边界就行了。
//orz
#include
using namespace std;
int t,k,n,m;
int ans[2010][2010],a[2010][2010],b[2010][2010];
void init(){
a[0][0]=1;
for (int i=1;i<=2001;++i){
a[i][0]=1;
for (int j=1;j<=i;++j){
a[i][j]=(a[i-1][j]+a[i-1][j-1])%k;
if (a[i][j]==0){
b[i][j]=1;
}
}
}
for (int i=1;i<=2001;++i)
for (int j=1;j<=2001;++j){
ans[i][j]=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]+b[i][j];
}
}
int main(){
//freopen("problem.in","r",stdin);
// freopen("problem.out","w",stdout);
cin>>t>>k;
init();
for (int i=1;i<=t;++i)
{
scanf("%d%d",&n,&m);
printf("%d\n",ans[n][m]);
}
}
T2 蚯蚓
题意很简单,用数组的三维一维存未切的,一维存切了之后第一段,一维存切了之后第二段,然后模拟切的过程就行了。结果只有65分,然后看题解发现需要单调队列优化。其实很容易证明,因为蚯蚓x切了之后每秒增长2p,而蚯蚓y未切每秒增长p,又因为x比y长所以x先切,所以在y切了后是肯定没有x切后的长的,所以满足单调性。(然而还是没a。。。)
//orz
#include
using namespace std;
int n,m,q,u,v,t,maxx,ans,sum,l;
int a[4][10000100],now[4],Left[4],b[10001000];
double p;
bool cmp(int a,int b){
return a>b;
}
int main(){
// freopen("earthworm.in","r",stdin);
// freopen("earthworm.out","w",stdout);
cin>>n>>m>>q>>u>>v>>t;
p=(double)u/v;
now[1]=now[2]=now[3]=1;
Left[1]=n;
for(int i=1;i<=n;++i){
scanf("%d",&a[1][i]);
}
sort(a[1]+1,a[1]+1+n,cmp);
for(int i=1;i<=m;++i){
ans=-1e9;
sum++;
for(int j=1;j<=3;++j)
if(now[j]<=Left[j])
if(ans
结果真的是状压dp,刚好碰到我复习的盲点了,本来想今天再复习状压dp(真没怎么学懂),然后一点都打不出来,只能直接骗样例。