标签:卡住 解法 red 速度 freopen har baidu one play
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+5; const int INF=1e9+5; int n,m,k,w,tot,minn=INF,mark; int f[1005][1005],a[1005],b[101],d[101]; template <class t>void red(t &x) { x=0; int w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) w=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=(x<<3)+(x<<1)+ch-‘0‘; ch=getchar(); } x*=w; } void input() { freopen("luogu.txt","r",stdin); freopen("lemon.out","w",stdout); } int main() { input(); red(n); red(m); red(k); red(w); while(n--) { memset(f,0x3f,sizeof(f)); for(int i=0;i<=m;++i) { f[i][i]=0; if(!i) continue; red(a[i]); } a[m+1]=w; for(int i=2;i<=m+1;++i) for(int j=0;j+i<=m+1;++j) { int e=j+i-1; for(int k=j;k<e;++k) if(f[j][k]+f[k+1][e]+a[e+1]-a[j]<f[j][e]) f[j][e]=f[j][k]+f[k+1][e]+a[e+1]-a[j]; } printf("%d\n",b[++tot]=f[0][m]); } for(int i=1;i<=tot;++i) if(b[i]<minn) { minn=b[i]; mark=i; } d[1]=0; for(int i=2;i<=tot;++i) d[i]=(d[i-1]+k)%i; printf("\n%d",1+abs(d[tot]+1-mark)); return 0
#include<bits/stdc++.h>using namespace std;const int maxn=1e6+5;const int INF=1e9+5;int n,m,k,w,tot,minn=INF,mark;int f[1005][1005],s[1005][1005],a[1005],b[101],d[101];template <class t>void red(t &x){ x=0; int w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) w=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=(x<<3)+(x<<1)+ch-‘0‘; ch=getchar(); } x*=w;}void input(){ freopen("input.txt","r",stdin); //freopen("lemon9.out","w",stdout);}int main(){ //input(); red(n); red(m); red(k); red(w); while(n--) { memset(f,0x3f,sizeof(f)); for(int i=0;i<=m;++i) { f[i][i]=0; s[i][i]=i; if(!i) continue; red(a[i]); } a[m+1]=w; for(int i=2;i<=m+1;++i) for(int j=0;j+i<=m+1;++j) { int e=j+i-1; for(int k=s[j][e-1];k<=s[j+1][e];++k) if(f[j][k]+f[k+1][e]+a[e+1]-a[j]<f[j][e]) { f[j][e]=f[j][k]+f[k+1][e]+a[e+1]-a[j]; s[j][e]=k; } } printf("%d\n",b[++tot]=f[0][m]); } for(int i=1;i<=tot;++i) if(b[i]<minn) { minn=b[i]; mark=i; } d[1]=0; for(int i=2;i<=tot;++i) d[i]=(d[i-1]+k)%i; printf("\n%d",1+abs(d[tot]+1-mark)); return 0;}
首先,它是道区间dp
然后,毒瘤的csy将它卡成了O(n^2)
所以,它是道要用四边形不等式优化的区间dp _(:з」∠)_
csy自己写标程的时候就在这儿卡了一下午
但毒瘤的csy还是不满足
所以,又有了更加丧心病狂的分柠檬,并且想卡成O(n)
然后,失败了QAQ
分柠檬原型是约瑟夫问题
然后,被我魔改了
其一般解法是模拟-》链表-》(特殊情况)公式
还有点良心的csy没有让大家被和她一样被链表折磨,于是本题用公式法(baidu)可解
csy的数据也蛮毒瘤的,在本地跑基本卡着上限过,不知道为什么到了luogu和mzoj上速度蜜汁快了一半,也不知道到底卡没卡住人 _(:з」∠)_
- 20~40 point
1,2,7,8的m=1,n《=1e3
O(n^3)可过
- 40~60 point
1,2,7,8,9,10
发现O(n^2)的暴力模拟第二问的方法
- 100 point
四边形不等式优化区间dp
公式优化约瑟夫问题
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+5; const int INF=1e9+5; int n,m,k,w,tot,minn=INF,mark; int f[1005][1005],s[1005][1005],a[1005],b[101],d[101]; template <class t>void red(t &x) { x=0; int w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) w=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=(x<<3)+(x<<1)+ch-‘0‘; ch=getchar(); } x*=w; } void input() { freopen("luogu.txt","r",stdin); freopen("lemon.out","w",stdout); } int main() { input(); red(n); red(m); red(k); red(w); while(n--) { memset(f,0x3f,sizeof(f)); for(int i=0;i<=m;++i) { f[i][i]=0; s[i][i]=i; if(!i) continue; red(a[i]); } a[m+1]=w; for(int i=2;i<=m+1;++i) for(int j=0;j+i<=m+1;++j) { int e=j+i-1; for(int k=s[j][e-1];k<=s[j+1][e];++k) if(f[j][k]+f[k+1][e]+a[e+1]-a[j]<f[j][e]) { f[j][e]=f[j][k]+f[k+1][e]+a[e+1]-a[j]; s[j][e]=k; } } printf("%d\n",b[++tot]=f[0][m]); } for(int i=1;i<=tot;++i) if(b[i]<minn) { minn=b[i]; mark=i; } d[1]=0; for(int i=2;i<=tot;++i) d[i]=(d[i-1]+k)%i; printf("\n%d",1+abs(d[tot]+1-mark)); return 0; }
标签:卡住 解法 red 速度 freopen har baidu one play
原文地址:https://www.cnblogs.com/Achensy/p/10886442.html