[Poi2015]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Poi2015]相关的知识,希望对你有一定的参考价值。

 

 

[POI2015]?asuchy

一看以为是sb题 简单来说就是每个人获得热量要尽量多 不能找别人

首先这道题好像我自己找不到NIE的情况

很容易想到一个优化 如果一个数/2>另一个数 那么一定选这个数

然后我想着其他的话就随便分配一个 然后会得出下一个 其实这样做是错的 因为你选完之后不知道下一个会不会是来降低我当前选的那一个的热量使得我当前的原来最优变成不是最优

 

然后这样子 怎么办呢??? 废话 膜题解

 

膜拜Claris 我们既然不知道下一个会不会来降低热量 不妨把每个食物的状态都定下来 让它们去dp下一个合法的状态

定义F[i][0-3]表示当前食物 0是两边都不选它 1是左边选 2是右边选 3是都选

那么的话而且保证已经解决i-1个 记录前驱的状态是什么

 

但是有一个细节 就是1和N的处理 我是把1再插后面 枚举食物1的状态 如果最后面的1还能维持原来的状态很明显合法

技术分享
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define Maxn 1000010
using namespace std;
int F[Maxn][4]; int N,C[Maxn]; int ans[Maxn];
void Do(int last)
{
  for(int i=N-1;i>=1;i--)
  {
     if(last==1) ans[i-1]=i;
     else if(last==2) ans[i]=i;
     else if(last==3) ans[i-1]=ans[i]=i;
     last=F[i][last];
  }
  for(int i=1;i<N-1;i++) printf("%d ",ans[i]); printf("%d\\n",ans[N-1]);
}

void DP()
{
  for(int i=2;i<=N;i++)
  {
    if((F[i-1][2]!=-1)&&(C[i-1]>=C[i])) F[i][0]=2;
    if((F[i-1][3]!=-1)&&(C[i-1]>=(C[i]*2))) F[i][0]=3;
    
    if((F[i-1][0]!=-1)&&(C[i-1]<=C[i])) F[i][1]=0;
    if((F[i-1][1]!=-1)&&(C[i-1]<=(C[i]*2))) F[i][1]=1;
    
    if((F[i-1][2]!=-1)&&((C[i-1]*2)>=C[i])) F[i][2]=2;
    if((F[i-1][3]!=-1)&&(C[i-1]>=C[i])) F[i][2]=3;

    if((F[i-1][0]!=-1)&&((C[i-1]*2)<=C[i])) F[i][3]=0;
    if((F[i-1][1]!=-1)&&(C[i-1]<=C[i])) F[i][3]=1;     
  }
}
int main()
{
  //freopen("a.in","r",stdin);
  //freopen("a.out","w",stdout);
  scanf("%d",&N);
  for(int i=1;i<=N;i++) scanf("%d",&C[i]); N++; C[N]=C[1];
  
  memset(F,-1,sizeof(F)); F[1][3]=1;
  DP();
  if(F[N][3]!=-1){ans[1]=1; ans[N-1]=1; Do(F[N][3]); return 0;}
  
  memset(F,-1,sizeof(F)); F[1][1]=1;
  DP();
  if(F[N][1]!=-1){ans[1]=2; ans[N-1]=1; Do(F[N][1]); return 0;}
  
  memset(F,-1,sizeof(F)); F[1][2]=1;
  DP();
  if(F[N][2]!=-1){ans[1]=1; ans[N-1]=N; Do(F[N][2]); return 0;}
  
  memset(F,-1,sizeof(F)); F[1][0]=1;
  DP();
  if(F[N][0]!=-1){ans[1]=2; ans[N-1]=N; Do(F[N][0]); return 0;}
  printf("NIE\\n");
  return 0;
}
View Code

 

 

[POI2015]Piecz??

题目的意思是要你用印章把原图的x盖满 枚举左上方的点和印章左上方的点对应 本来想写链表优化的 却发现没有我的暴力优...

然后复了一个读入优化 谢谢

技术分享
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#define Maxn 1010
using namespace std;
pair<int,int> Q[Maxn*Maxn]; int tail;
int N,M; int A,B; int Tcase;
int str[Maxn][Maxn]; int st[Maxn][Maxn]; bool bo[Maxn][Maxn];
inline int cread() {  
    char ch = getchar(); for(; ch != x && ch != .; ch = getchar());  
    return ch == x;  
}  
int main()
{
  //freopen("a.in","r",stdin);
  //freopen("a.out","w",stdout);
  scanf("%d",&Tcase);
  while(Tcase--)
  {
    scanf("%d%d%d%d",&N,&M,&A,&B);
    for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) str[i][j]=cread();
    for(int i=0;i<A;i++) for(int j=0;j<B;j++) st[i][j]=cread();
    
    pair<int,int>ST;
    
    bool bk=false;
    for(int i=0;i<A;i++){for(int j=0;j<B;j++) if(st[i][j]){ST=make_pair(i,j); bk=true; break;} if(bk) break;}
    tail=0; for(int i=0;i<A;i++) for(int j=0;j<B;j++) if(st[i][j]){Q[++tail]=make_pair(i-ST.first,j-ST.second);}
     
    memset(bo,0,sizeof(bo)); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) if(str[i][j]) bo[i][j]=1; 
     
    bk=true;
    for(int i=1;i<=N;i++)
    {
      for(int j=1;j<=M;j++)
      {
        if(bo[i][j])
        {
          int k;
          for(k=1;k<=tail;k++)
          {
            if((i+Q[k].first>N)||(j+Q[k].second>M)) break;
            if(!bo[i+Q[k].first][j+Q[k].second]) break;
            bo[i+Q[k].first][j+Q[k].second]=0;
          }
          if(k!=tail+1){bk=false; break;}
        }
      }
      if(!bk) break;
    }
    if(!bk) printf("NIE\\n");
    else printf("TAK\\n");
  }
  return 0;
}
View Code

 

以上是关于[Poi2015]的主要内容,如果未能解决你的问题,请参考以下文章

java poi xwpf操作word生成一个表格怎么合并单元格,求大神指导!

VS2015 代码片段整理

VS2015使用技巧 打开代码片段C#部分

雷林鹏分享:Apache POI电子表格/Spreadsheet

雷林鹏分享:Apache POI电子表格/Spreadsheet

Java-poi-excel-对空值单元格的读取