A:消失之物
背包变种,设n为物品数量,nums[i]为物品的重量,dp1[i][j] 为前i个物品放入容量为j的背包中的方案数目,那么显然有:
dp1[i][j] = sum{dp1[i-1][j-nums[i]]};
那么所有的物品放入容量为j的数目是dp1[n][j];
令dp2[i][j]为除去第i个物品,放入容量为j的背包中的方案数目:
dp2[i][j] = dp1[n][j] - dp2[i][j-nums[i]],表示从选择所有物品装的方案中,筛去包含i物品的方案数
代码:
#include <stdio.h>
#include <string.h>
const int N = 2002;
int dp[N];
int dp2[N];
int n,m;
int nums[N];
void ZeroOnePage()
{
}
void Test()
{
for(int i = 1; i<= n; ++i)
{
scanf("%d",&nums[i]);
}
memset(dp,0,sizeof(dp));
memset(dp2,0,sizeof(dp2));
dp[0] = 1;
for(int i = 1; i <= n; ++i)//前i个物品
{
for(int j = m; j >= nums[i]; --j)
{
dp[j] = (dp[j] + dp[j - nums[i]])%10;
}
}
for(int j = 0; j <= m; ++j)
dp2[j] = dp[j];
for(int i = 1; i <= n; ++i)//前i个物品
{
for(int j = nums[i]; j <= m; ++j)
{
dp2[j] = ((dp[j] - dp2[j - nums[i]])%10 + 10)%10;
}
for(int j = 1; j <= m; ++j)
{
printf("%d",dp2[j]);
}
printf("\n");
for(int j = 0; j <= m; ++j)
dp2[j] = dp[j];
}
}
int main()
{
while(scanf("%d %d",&n,&m) != EOF)
{
Test();
}
return 0;
}
F:永远挑战
最短路SPFA
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <queue>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
const int INF = 1 << 25;
const int N = 100005;
struct Edge
{
int to;
int weight;
friend bool operator < (const Edge& _e1,const Edge& _e2)
{
return _e1.weight < _e2.weight;
}
};
vector<Edge> vecGraph[N];
map<int,int> Map;
int n,m;
void Input()
{
for(int i = 0; i < n; ++i)
{
vecGraph[i].clear();
}
Map.clear();
int a,b,w;
Edge edge1;
for(int i = 0; i < m; ++i)
{
scanf("%d %d %d",&(a),&(b),&(w));
--(a);
--(b);
edge1.to = b;
edge1.weight = w;
Map[a*N+b] = w;
vecGraph[a].push_back(edge1);
}
//debug
/**//*for(int i = 0 ; i < p; ++i)
{
printf("%d: ",i);
for(int j = 0 ; j < vecGraph[i].size(); ++j)
printf("%d(%d) ",vecGraph[i][j].to,vecGraph[i][j].weight);
printf("\n");
}*/
}
int distances[N];
bool visited[N];
void SPFA(const int _s,int &_ans)
{
queue<int> Queue;
Queue.push(_s);
bool IsInQueue[N];
for(int i = 0; i < n; ++i)
{
distances[i] = INF;
IsInQueue[i] = false;
}
int to;
Edge tmpEdge;
IsInQueue[_s] = true;
distances[_s] = 0;
int curState;
//do
while(!Queue.empty())
{
curState = Queue.front();
Queue.pop();
for(int i = 0; i < vecGraph[curState].size(); ++i)
{
to = vecGraph[curState][i].to;
map<int,int>::iterator iter = Map.find(curState*N+to);
if(iter != Map.end() && distances[to] > distances[curState] + iter->second)
{
distances[to] = distances[curState] + iter->second;
if(!IsInQueue[to])
{
IsInQueue[to] = true;
Queue.push(to);
}
}
}
IsInQueue[curState] = false;
}
_ans = distances[n-1];
}
void solve()
{
int ans = INF;
SPFA(0,ans);
printf("%d\n",ans);
}
void Test()
{
Input();
solve();
}
int main()
{
while(scanf("%d %d",&n,&m) != EOF)
Test();
return 0;
}
G:吉他英雄
置换群计数
#include <stdio.h>
#include <algorithm>
using namespace std;
int nums[60];
int n;
void Test()
{
scanf("%d",&n);
int sum = 0;
for(int i = 0; i < n; ++i)
{
scanf("%d",&nums[i]);
sum += nums[i];
}
sort(nums,nums+n);
double ans = sum + nums[n-2];
ans /= 2;
printf("%.6lf\n",ans);
}
int main()
{
int tc = 0;
scanf("%d",&tc);
for(int i = 0; i < tc;++i)
{
Test();
}
return 0;
}
I:我爱你啊
状态机,从前面一直按顺序匹配则可
#include <stdio.h>
#include <string.h>
char chs[10] = "luvletter";
char context[100005];
int len;
int cnt;
void runState(char* _context,int _begin)
{
int state = 0;
int i = _begin;
int pos[9] = {0};
while(i < len)
{
if(_context[i] == chs[state])
{
pos[state] = i;
++state;
if(state == 9)
{
cnt++;
state = 0;
}
}
++i;
}
}
int main()
{
int tc = 0;
//freopen("data2.txt","r",stdin);
scanf("%d",&tc);
for(int i = 0; i < tc; ++i)
{
while(gets(context),len = strlen(context),len == 0);
int k = 0;
cnt = 0;
runState(context,0);
printf("%d\n",cnt);
}
if(tc == 0)
printf("0\n");
return 0;
}
J:随机种子
首先要满足条件2:
a 的十进制表示包含0到9,而且数的范围是10^16,故先构造一数满足此条件:
设d为数字X的长度,那么有:
1234567890*10^d,
这样可以在10^d内凑数字,而且进一步知道,一个数X在一个长度为X的区间里面,必然能找到一个被X整除的数,故此可构造空间
[1234567890*10^d,1234567890*10^d+ X - 1]
然后枚举测试
#include <stdio.h>
#include <string.h>
#include <math.h>
const long long K = 1234567890;
int getLen(int _value)
{
int cnt = 0;
while(_value > 0)
{
++cnt;
_value /= 10;
}
return cnt;
}
void getAns(int _x)
{
int d = getLen(_x);
long long begin = K*(int)(pow(10.0,(double)d));
long long end = begin + _x -1;
for(long long j = begin; j <= end; ++j)
{
if(j % _x == 0)
{
printf("%lld\n",j);
return;
}
}
printf("-1\n");
}
int main()
{
//freopen("data5.txt","w",stdout);
int tc;
int X;
scanf("%d",&tc);
for(int i = 0; i < tc; ++i)
{
scanf("%d",&X);
if(X == 0)
{
printf("-1\n",X);
continue;
}
getAns(X);
}
return 0;
}
posted on 2011-04-11 15:59
bennycen 阅读(1857)
评论(3) 编辑 收藏 引用 所属分类:
算法题解