WHUST 2015 Summer Contest #11
网址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=89986#overview
自己一个人做的好醉……………………
题意: 1<=k<=n<=100 k个人在n天中做饭,没人至少做一天的饭,问一共有多少种情况。。 自己犯了2B错误,容斥公式写错了。DP理解不了,纠结了一天。。
import java.util.*; import java.io.*; import java.math.*; public class Main { /** * @param args */ public static void main(String[] args) throws FileNotFoundException { // TODO Auto-generated method stub Scanner cin = new Scanner (new File("dinner.in")); PrintWriter cout = new PrintWriter(new File("dinner.out")); //Scanner cin = new Scanner (System.in); BigInteger [][] C = new BigInteger [110][110]; C[0][0]=BigInteger.ONE; for (int i=1;i<=100;i++) { C[i][0]=C[i][i]=BigInteger.ONE; for (int j=1;j<i;j++) { C[i][j] = BigInteger.ZERO; C[i][j]=C[i][j].add(C[i-1][j-1]); C[i][j]=C[i][j].add(C[i-1][j]); } } int n,k; while(cin.hasNext()) { BigInteger ans = BigInteger.ONE; k = cin.nextInt(); n = cin.nextInt(); for (int i=1;i<=n;i++) { BigInteger tmp = new BigInteger(String.valueOf(k)); ans = ans.multiply(tmp); } int cur=0; for (int i=1;i<=k;i++){ BigInteger tp = C[k][i]; for (int j=1;j<=n;j++) { BigInteger tmp = new BigInteger(String.valueOf(k-i)); tp = tp.multiply(tmp); } if (cur==0) { ans=ans.subtract(tp); } else { ans=ans.add(tp); } //System.out.println(tp); //System.out.println(ans); cur=1-cur; } cout.println(ans); //System.out.println(ans); } cin.close(); cout.close(); } }
题意:类似poj一道窗格移动的题目,裸的单调队列, 但是那个z=f(y), -2^31<=z<=2^31-1 y-z可以被2^32整除, 这个东西看得有点醉, 不理解, 后来别人说了下是自然溢出的意思…………
#include<bits/stdc++.h> #define maxn 30000010 using namespace std; int f[maxn]; struct node { int x,y; node(int x, int y):x(x),y(y){} }; deque<node> Q; int main(void) { freopen("minima.in","r",stdin); freopen("minima.out","w",stdout); int n,m,k,a,b,c; scanf("%d%d%d%d%d%d",&n,&m,&k,&a,&b,&c); for (int i=1;i<=k;i++) scanf("%d",&f[i]); for (int i=k+1;i<=n;i++) f[i]=a*f[i-2]+b*f[i-1]+c; //for (int i=1;i<=n;i++) f[i]=i;//printf("%d ",f[i]); for (int i=1;i<=m;i++) { while(!Q.empty()&&f[i]<=Q.back().x) Q.pop_back(); Q.push_back(node(f[i],i)); } long long ans=Q.front().x; //cout<<ans<<endl; for (int i=m+1;i<=n;i++) { while(!Q.empty()&&i-Q.front().y>=m) Q.pop_front(); while(!Q.empty()&&(f[i]<=Q.back().x||Q.back().y-i>=m)) Q.pop_back(); Q.push_back(node(f[i],i)); ans+=Q.front().x; //cout<<Q.front().x<<" "; } cout<<ans<<endl; } /* 10 3 2 1 1 0 0 1 */
题意:给定一个有向无权图,问存在多少 i->j->k->i 这样的圈。。
解法:利用bitset优化, 一个很巧妙的方法存储下边和反边, 那么对于每一对(i,j) 结果就是 (f[i]&g[j]).cout(), 累加就是最后结果
#include<bits/stdc++.h> #define maxn 1510 using namespace std; bitset<maxn> f[maxn],g[maxn]; char s[maxn][maxn]; int main(void) { freopen("triatrip.in","r",stdin); freopen("triatrip.out","w",stdout); int n; scanf("%d",&n); for (int i=0;i<n;i++) { scanf("%s",s[i]); f[i].reset(); g[i].reset(); } for (int i=0;i<n;i++) for (int j=0;j<n;j++) { if (s[i][j]=='+') f[i][j]=1,g[j][i]=1; } long long ans=0; for (int i=0;i<n;i++) for (int j=0;j<n;j++) { if (f[i][j]) ans+=(f[j]&g[i]).count(); } cout<<ans/3<<endl; } /* 4 --+- +--+ -+-- --+- */